Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset |
# region imports from AlgorithmImports import * from statistics import stdev # endregion class MeasuredTanTermite(QCAlgorithm): stopMarketTicket = None stopMarketFillTime = datetime.min highestprice = 0 def Initialize(self): self.SetStartDate(2022, 6, 1) self.SetEndDate(2022, 6, 2) self.SetCash(1000000) self.rebalanceTime = datetime.min self.AddUniverse(self.CoarseSelectionFilter, self.FineSelectionFilter) self.UniverseSettings.Resolution = Resolution.Second #resolution of the securities in the universe, default is minute self.AddEquity("SPY") self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.BeforeMarketClose("SPY", 1), self.ExitPositions) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.Every(timedelta(seconds=5)), self.GoFast) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.At(9, 30, 20), self.ScanTargets) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.Midnight, self.ClearFills) self.Data = {} self.open_prices = {} self.Targets = {} self.ValueCheck= {} self.filled_today = {} self.banned_tickers = {} self.highest_price_list = {} self.pricedata = {} self.myOrder = None self.highestprice = 0 self.highesttime = 0 self.lowprice = 10000000 self.lowpricetime = 0 self.buylines = {} def GoFast (self): for symbol in self.Targets.keys(): symbolData = self.Data[symbol] if not symbolData.IsReady: continue if not (self.Time.hour >= 9 and self.Time.minute >= 30 and self.Time.second >= 20): #let at least two data points enter for the rolling window of the previous day to finish return open_orders = self.Transactions.GetOpenOrders(symbol) price = self.Securities[symbol].Price if price > self.highestprice: self.highestprice = price self.highesttime = self.Time if price < self.lowprice: self.lowprice = price self.lowpricetime = self.Time if not self.Portfolio[symbol].Invested and len(open_orders) == 0 and symbol not in self.filled_today.keys() and symbol.Value not in self.banned_tickers.keys(): self.filled_today[symbol] = SymbolData(self, symbol) if (self.Time.hour == 15 and self.Time.minute == 59 and self.Time.second == 30) and symbol in self.filled_today.keys(): self.Log(",Symbol," + str(symbol.Value) + ",HighestPrice," + str(self.highestprice) + ",TimeofHigh," + str(self.highesttime) + ",LowestPrice," + str(self.lowprice) + ",TimeofLOw," + str(self.lowpricetime)) self.highestprice = 0 self.lowprice = 0 def ExitPositions(self): self.Targets = {} self.ValueCheck= {} def ClearFills(self): self.filled_today = {} self.banned_tickers = {} def ScanTargets(self): for symbol in self.Data.keys(): symbolData = self.Data[symbol] if not symbolData.IsReady: continue # this loop blocks tickers that have no price action day to day k = 0 t = 0 while t <= 4: if symbolData.Bars[t].High == symbolData.Bars[t+1].High and symbolData.Bars[t].Low == symbolData.Bars[t+1].Low or symbolData.Bars[t].Close == symbolData.Bars[t].Open: t += 1 k += 1 else: t += 1 if symbol not in self.Targets.keys() and symbolData.Bars[0].High > symbolData.Bars[1].Close: if symbol.Value in self.ValueCheck.keys(): #fixes a known QC issue where multiple tickers trade the same underlying ticker (happens with buyouts or acquisitions) self.banned_tickers[symbol.Value] = SymbolData(self, symbol) else: avevolume = 0 k = 0 while k <= 5: avevolume += symbolData.Bars[k].Volume k += 1 avevolume = avevolume/k self.Targets[symbol] = SymbolData(self, symbol) self.ValueCheck[symbol.Value] = SymbolData(self, symbol) self.Log(",Symbol," + str(symbol.Value) + ",Open," + str(self.Securities[symbol].Open) + ",Market," + str(symbol.ID.Market) + ",ave 5 day volume," + str(avevolume)) def CoarseSelectionFilter(self, coarse): #updates at midnight during backtesting, and around 6-7am in live trading, based on previous day data if self.Time <= self.rebalanceTime: return self.Universe.Unchanged self.rebalanceTime = self.Time + timedelta(35) symbols_by_price = [c for c in coarse if c.Price > 1 and c.Price < 25 and c.HasFundamentalData and c.Volume > 50000 and len(c.Symbol.Value) <= 4 and c.Market == 'usa'] self.filteredByPrice = symbols_by_price[:650] return [c.Symbol for c in self.filteredByPrice] def FineSelectionFilter(self, fine): sortedByMarketCap = sorted(fine, key=lambda c: c.MarketCap) symbols_by_marketcap = [c for c in sortedByMarketCap if c.MarketCap > 0] self.filteredBymarketcap = symbols_by_marketcap for c in symbols_by_marketcap: self.Log(",Symbol," + str(c.Symbol.Value) + ",MarketCap," + str(c.MarketCap)+ ",Price," + str(c.Price) + ",IPO," + str(c.SecurityReference.IPODate)+ ",IsREIT," + str(c.CompanyReference.IsREIT) + ",LastEarningsDate," + str(c.EarningReports.FileDate) + ",CompanyProfile.EnterpriseValue," + str(c.CompanyProfile.EnterpriseValue)+ ",FinancialHealthGrade," + str(c.AssetClassification.FinancialHealthGrade)+ ",ProfitabilityGrade," + str(c.AssetClassification.ProfitabilityGrade)+ ",SizeScore," + str(c.AssetClassification.SizeScore)+ ",ValueScore," + str(c.AssetClassification.ValueScore)+ ",GrowthScore," + str(c.AssetClassification.GrowthScore) + ",Sector," + str(c.AssetClassification.MorningstarSectorCode) + ",Sphere," + str(c.AssetClassification.MorningstarEconomySphereCode) + ",IndustryGroup," + str(c.AssetClassification.MorningstarIndustryGroupCode)) return [c.Symbol for c in self.filteredBymarketcap] def OnSecuritiesChanged(self, changes): for security in changes.AddedSecurities: symbol = security.Symbol if symbol not in self.Data: self.Data[symbol] = SymbolData(self, symbol) for security in changes.RemovedSecurities: symbol = security.Symbol if symbol in self.Data: symbolData = self.Data.pop(symbol, None) self.SubscriptionManager.RemoveConsolidator(symbol, symbolData.consolidator) class SymbolData: def __init__(self, algorithm, symbol): self.algorithm = algorithm self.symbol = symbol self.Bars = RollingWindow[TradeBar](7) self.consolidator = TradeBarConsolidator(timedelta(days=1)) self.consolidator.DataConsolidated += self.OnDataConsolidated algorithm.SubscriptionManager.AddConsolidator(symbol, self.consolidator) def OnDataConsolidated(self, sender, bar): self.Bars.Add(bar) @property def IsReady(self): return self.Bars.IsReady