Overall Statistics |
Total Trades 500 Average Win 2.31% Average Loss -7.12% Compounding Annual Return 52.124% Drawdown 64.300% Expectancy 0.043 Net Profit 75.216% Sharpe Ratio 1.037 Probabilistic Sharpe Ratio 39.401% Loss Rate 21% Win Rate 79% Profit-Loss Ratio 0.32 Alpha 0.668 Beta -0.362 Annual Standard Deviation 0.644 Annual Variance 0.414 Information Ratio 0.99 Tracking Error 0.674 Treynor Ratio -1.843 Total Fees $2207.08 Estimated Strategy Capacity $870000.00 Lowest Capacity Asset HILS XV2E35288YG5 |
#region imports from AlgorithmImports import * #endregion import datetime #import timedelta, time import math from QuantConnect.Data.UniverseSelection import * from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel FAST = 10; SLOW = 2000; THRESOLD = 30; FASTER = 1; SLOWER = 60; """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Symbol Data """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" class SymbolData(object): def __init__(self, algorithm, symbol, criteriaDict): self.symbol = symbol self.symbolValue = symbol.Value self.macd = MovingAverageConvergenceDivergence( FAST, SLOW, MovingAverageType.Simple) self.sma = MovingAverageConvergenceDivergence( FASTER, SLOWER, MovingAverageType.Simple) self.smav = SimpleMovingAverage(30) self.is_uptrend = False self.algorithm = algorithm self.criteriaDict = criteriaDict self.highestTrailStopPrice = -1 self.tradeLock = False self.current = None self.smaDictionary = {} self.selectedSymbols = {} self.avg = {} self.BuyIn = {} def update(self, time, value): if self.smav.Update(time, value): smav = self.smav.Current.Value self.is_uptrend = smav > 500000 class ErrorSubmission_TrailStop(QCAlgorithm): """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Iniitalization """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" def Initialize(self): #-- Date Range self.SetStartDate(2021, 3, 1) # Set Start Date self.SetEndDate(2022, 7, 4) # Set End Date #-- Starting Equity self.SetCash(10000) # Set Strategy Cash # check if will be replaced self.UniverseSettings.Resolution = Resolution.Minute self.AddUniverse(self.CoarseFilterSelection, self.FineFilterSelection) #---------- Universe Selection ------------- self.handpicked_SymbolList = [ #Symbol.Create("AGRX", SecurityType.Equity, Market.USA), #Symbol.Create("AGRI", SecurityType.Equity, Market.USA), #Symbol.Create("COSM", SecurityType.Equity, Market.USA), #Symbol.Create("HCDI", SecurityType.Equity, Market.USA), #Symbol.Create("HILS", SecurityType.Equity, Market.USA), #Symbol.Create("KAVL", SecurityType.Equity, Market.USA), #Symbol.Create("LLL", SecurityType.Equity, Market.USA), #Symbol.Create("MITQ", SecurityType.Equity, Market.USA), ] #---------- Alpha Generation ------------- #-- Criteria Settings self.criteriaDict = { } self.averages = {} self.smavolume = {} #---------- Portfolio Construction ------------- #self.maxSymbolsToTrade = 10 # maxSymbols to trade self.symbolDict = {} # list which stores symbols (refreshes with universe updates + handpick selection) self.symbolWithPositionDict = {} # list which stores symbols with position self.potentialTradeDict = {} # temp list to store potential symbols to trade for symbol in self.handpicked_SymbolList: if symbol not in self.symbolDict: self.AddEquity(symbol.Value, Resolution.Minute, Market.USA)#, True, 1, True) self.symbolDict[symbol] = SymbolData(self, symbol, self.criteriaDict) #-----------On Ordered Events----------- #symbolData = self.symbolDict[symbol] #---------- Schedule to run calculation ------------- #self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.Every(TimeSpan.FromMinutes(10)), self.runAlgo) #-----------Trading Volume Oscillator--------- self.vo ={} self.SetWarmUp(SLOW, Resolution.Minute) self.sm = {} self.smavol = {} self.BuyIn = {} """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OnData """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" def OnSecuritiesChanged(self, changes): # self.Log("OnSecuritiesChanged: " + str(self.Time)) self.Log(f'New Securities Added: {[security.Symbol.Value for security in changes.AddedSecurities]}') for security in changes.RemovedSecurities: if ((security.Symbol in self.symbolDict) and (security.Symbol not in self.handpicked_SymbolList) and (security.Symbol not in self.symbolWithPositionDict)): # self.Log("Removing " + security.Symbol.Value + " from symbolDict") del self.symbolDict[security.Symbol] for security in changes.AddedSecurities: if security.Symbol not in self.symbolDict: # self.Log("Adding " + security.Symbol.Value + " to symbolDict") self.AddEquity(security.Symbol.Value, Resolution.Minute) self.symbolDict[security.Symbol] = SymbolData(self,security.Symbol,self.criteriaDict) self.averages[security.Symbol] = SymbolData(self,security.Symbol,self.criteriaDict) #self.smavolume[security.Symbol] = self.SMA(security.Symbol, 30, Resolution.Daily) def OnData(self, data): if self.IsWarmingUp: return for symbol in self.symbolDict: symbolData = self.symbolDict[symbol] if data.Bars.ContainsKey(symbol): symbolData.macd.Update(data[symbol].EndTime, data[symbol].Volume) symbolData.sma.Update(data[symbol].EndTime, data[symbol].Price) symbolData.smav.Update(data[symbol].EndTime, data[symbol].Volume) if symbolData.smav.IsReady and symbolData.macd.Slow.Current.Value > 0: self.vo[symbol] = symbolData.macd.Fast.Current.Value / symbolData.macd.Slow.Current.Value self.sm[symbol] = symbolData.sma.Fast.Current.Value / symbolData.sma.Slow.Current.Value self.smavol[symbol] = symbolData.smav.Current.Value else: self.vo[symbol] = -1 self.sm[symbol] = -1 else: self.vo[symbol] = -1 self.sm[symbol] = -1 # Updates the SymbolData object with current EOD price rising = [] selected = [] for symbol in self.symbolDict: symbolData.CurrentPrice = self.Securities[symbol].Price if symbol not in selected and self.vo[symbol] > THRESOLD and self.sm[symbol] > 1.05 and self.smavol[symbol] > 500000: selected.append(symbol) self.BuyIn[symbol] = symbolData.CurrentPrice #if len(selected) == 0: #self.Liquidate() #for symbol in rising: #symbolData = self.symbolDict[symbol] #symbolData.CurrentPrice = self.Securities[symbol].Price #if (self.BuyIn[symbol] * 1.5) < symbolData.CurrentPrice: # selected.append(symbol) #self.Debug("2nd") #self.Debug(symbol) #else: for symbol in selected: symbolData = self.symbolDict[symbol] symbolData.CurrentPrice = self.Securities[symbol].Price if not symbolData.tradeLock and not self.Portfolio[symbol].Invested: symbolData.BuyIn = symbolData.CurrentPrice symbolData.current = self.Time cash = self.Portfolio.Cash available = (cash *.25) purchase = math.floor(available / symbolData.CurrentPrice) self.MarketOrder(symbol, -purchase) self.Debug(symbol) self.Debug("Volume") self.Debug(purchase) self.Debug(symbolData.macd.Fast.Current.Value) self.Debug(symbolData.macd.Slow.Current.Value) self.Debug("Price") self.Debug(symbolData.sma.Fast.Current.Value) self.Debug(symbolData.sma.Slow.Current.Value) self.Debug("Average") self.Debug(symbolData.smav.Current.Value) self.AddEquity(symbol.Value, Resolution.Minute) self.symbolWithPositionDict[symbol] = SymbolData(self,symbol,self.criteriaDict) else: if self.Securities[symbol].Price > symbolData.highestTrailStopPrice: symbolData.highestTrailStopPrice = self.Securities[symbol].Price #for symbol in selected: #self.Debug("buy") #self.Debug(symbol) #self.Debug(self.vo[symbol]) #spynum = self.CalculateOrderQuantity(sec, 1) #self.stopMarketTicket = self.StopMarketOrder(sec, spynum, 0.95 * self.Securities[sec].Close) for symbol in list(self.symbolWithPositionDict): symbolData = self.symbolDict[symbol] if self.Securities[symbol].Price < symbolData.BuyIn * .92 or self.Securities[symbol].Price > symbolData.BuyIn * 1.2 or (self.Time - symbolData.current).days == 14: # self.Securities[symbol].Price < symbolData.highestTrailStopPrice * .9 self.SetHoldings(symbol, 0) symbolData.tradeLock = True #self.handpicked_SymbolList.pop(symbol) #self.Debug("sell") #self.Debug(symbol) #self.Debug(self.vo[symbol]) #lass LiquidValueUniverseSelectionModel(FundamentalUniverseSelectionModel): #def __init__(self): #super().__init__(True, None) #self.lastMonth = -1 #self.volumeBySymbol = {} #self.criteriaDict = {} def CoarseFilterSelection(self, coarse): # update once per month #if self.lastMonth == algorithm.Time.month: #return Universe.Unchanged #self.lastMonth = algorithm.Time.month # sort by dollar volume and if they have fundamental Data, in decending order filtered = [ x for x in coarse]# if x.Price < 30] return [x.Symbol for x in filtered] def FineFilterSelection(self, fine): sortedByShares = sorted(fine, key = lambda f: f.CompanyProfile.SharesOutstanding, reverse = True) universe = [f for f in sortedByShares if f.CompanyProfile.SharesOutstanding < 15000000 and f.MarketCap < 2000000000] ''' fine = [x for x in universe if x.EarningReports.FileDate + timedelta(days=0) > self.Time > x.EarningReports.FileDate + timedelta(days=3) and x.EarningReports.FileDate != datetime.time()] ## Iterate through symbols for symbol in fine: history = self.History(symbol, 20, Resolution.Daily) ## Find hsitory for specific symbol symbolVolumeHistory = history.loc[str(symbol)] ## Create SMA for symbol and register it with algorithm symbolSMA = SimpleMovingAverage(20) ## Iterate through historical data for tuple in symbolVolumeHistory.itertuples(): ## Update SMA with data time and volume symbolSMA.Update(tuple.Index, tuple.volume) self.Debug(f'Updating {symbol.Value} SMA...') ## Add SMA to dictionary so you can access it later self.smaDictionary[symbol] = symbolSMA ## Perform SMA filtering conditions and select/return the symbols you want to add to your universe ## Fine Selection will use only these ones selectedSymbols = [x for x in fine if self.smaDictionary[symbol].symbolSMA > 50000] ''' return [x.Symbol for x in universe]