Overall Statistics |
Total Trades 62 Average Win 0.60% Average Loss -0.78% Compounding Annual Return -25.389% Drawdown 9.500% Expectancy -0.143 Net Profit -3.546% Sharpe Ratio -1.769 Probabilistic Sharpe Ratio 14.011% Loss Rate 52% Win Rate 48% Profit-Loss Ratio 0.77 Alpha -0.259 Beta 0.023 Annual Standard Deviation 0.14 Annual Variance 0.02 Information Ratio -2.765 Tracking Error 0.262 Treynor Ratio -10.814 Total Fees $233.51 |
from Risk.MaximumDrawdownPercentPerSecurity import MaximumDrawdownPercentPerSecurity class TransdimensionalParticleThrustAssembly(QCAlgorithm): def Initialize(self): self.SetStartDate(2020, 6, 1) # Set Start Date self.SetEndDate(2020, 7, 15) # Set End Date self.SetCash(100000) # Set Strategy Cash self.AddEquity("SPY", Resolution.Minute).SetDataNormalizationMode(DataNormalizationMode.SplitAdjusted) # Add SPY to set scheduled events self.UniverseSettings.Resolution = Resolution.Minute # Setting Universe: Daily, Minute or Second self.UniverseSettings.FillForward = False # self.UniverseSettings.ExtendedMarketHours = False # self.UniverseSettings.Leverage = 1.0 self.SetUniverseSelection(FineFundamentalUniverseSelectionModel(self.CoarseSelectionFunction, self.FineSelectionFunction, None, None)) # self.SetUniverseSelection(QC500UniverseSelectionModel()) self.SetRiskManagement(MaximumDrawdownPercentPerSecurity(0.2)) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 2), self.Rebalance) # Our Scheduled Events self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.BeforeMarketClose("SPY", 30), self.LiquidatePositions) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.BeforeMarketClose("SPY", 1), self.OnMarketClose) #self.Schedule.On(self.DateRules.Every(DayOfWeek.Friday) , self.TimeRules.BeforeMarketClose("SPY", 35), self.GetTopPerformers) self.previousClose = {} # Dictionary to keep track of previous close for each symbol #self.Spliteventbefore = {} #self.Spliteventafter = {} self.donottrade = [Symbol.Create(ticker, SecurityType.Equity, Market.USA) for ticker in []] #['HUGE']]#, 'MSFT']] self.cashused = 10000 def OnData(self, data): # OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. pass #for sec in self.Portfolio: #currentprice = self.Securities[symbol].Price #purchaseprice = self.Portfolio[sec].AveragePrice x 1.2 #if sec.UnrealizedProfitPercent < .2: # currentprice > purchaseprice x 1.2: #self.Liquidate() def CoarseSelectionFunction(self, coarse): # Picks up securities Universe. Constructed at midnight of night before. return [x.Symbol for x in coarse if 100 > x.Price > 1] def FineSelectionFunction(self, fine): # Picks up securities from Coarse > Universe. Constructed at midnight of night before. return [x.Symbol for x in fine if x.MarketCap > 1000000000] def OnSecuritiesChanged(self, changes): # Picks up securities from the Fine > Coarse > Universe. Constructed at midnight of night before. for security in changes.AddedSecurities: # AddedSecurities are those populated by Fine > Coarse > Universe, for security in self.ActiveSecurities.Values if security.Symbol in self.donottrade: continue symbol = security.Symbol ## self.Spliteventbefore[symbol] = self.Value.SplitFactor[symbol] if symbol not in self.previousClose: # Make a history call for symbol to get last closing price history = self.History(symbol, 1, Resolution.Daily) #, DataNormalizationMode.SplitAdjusted) if not history.empty: history = history.close.unstack(0)[symbol] if not history.empty: self.previousClose[symbol] = history[0] for security in changes.RemovedSecurities: # Remove symbols from previous close as they are removed from the universe symbol = security.Symbol self.previousClose.pop(symbol, None) def Rebalance(self): percentChange = {} # Dictionary to keep track of percent change from last close priceoverTwo = {} for symbol, previousClose in self.previousClose.items(): # Populate Dictionary ## if self.Splits.ContainsKey(symbol): ## continue if self.CurrentSlice.ContainsKey(symbol): ## self.Spliteventafter[symbol] = self.Value.SplitFactor[symbol] ## if self.Spliteventbefore[symbol] == self.Spliteventafter[symbol]: price = self.CurrentSlice[symbol].Close change = price/previousClose percentChange[symbol] = change priceoverTwo[symbol] = price symbols = list(percentChange.keys()) # Symbols under consideration sortedSymbols = sorted([x for x in symbols if percentChange[x] < 1 and priceoverTwo[x] > 1], key=lambda x : percentChange[x], reverse = False) # True is Highest first selected = sortedSymbols[:1] # Get xx symbols #history_data = self.History(self.Symbol("ZIV"), 30, Resolution.Daily).close.unstack(level=0) #history_data = history_data['ZIV'] #change = history_data.pct_change().dropna() #volatility = change.std(ddof=1) for symbol in selected: price = self.Securities[symbol].Price self.MarketOrder(symbol, self.cashused/price) #self.StopMarketOrder(symbol, -self.cashused/price, price*1.2) # Stop loss 20% higher than purchase price def LiquidatePositions(self): self.Liquidate() # Liquidate portfolio def OnMarketClose(self): for symbol in self.previousClose: # Store new previous close values if self.CurrentSlice.ContainsKey(symbol): self.previousClose[symbol] = self.CurrentSlice[symbol].Close ## self.Spliteventbefore[symbol] = self.Value.SplitFactor[symbol] #1 #for kvp in self.Portfolio: # Store cumulative performance for symbols in portfolio # symbol = kvp.Key # holding = kvp.Value # if holding.Invested: # if symbol not in self.performance: # self.performance[symbol] = holding.UnrealizedProfitPercent # else: # self.performance[symbol] = self.performance[symbol] + holding.UnrealizedProfitPercent #def GetTopPerformers(self): #symbols = list(self.performance.keys()) # Symbols under consideration #sortedSymbols = sorted(symbols, key=lambda x: self.performance[x], reverse=True) # Symbols sorted by performance #self.top = sortedSymbols[:10] # Top 10 performers #self.performance = {} # Reset performances #sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True) #Sort descending by daily dollar volume #return [ x.Symbol for x in sortedByDollarVolume[:self.__numberOfSymbols] ] #Return the symbol objects of the 'NumberOfSymbols' top entries from our sorted collection #c_filter = sorted([x for x in coarse if x.HasFundamentalData and 13 > x.Price > 1], key=lambda x: x.DollarVolume, reverse=True)[:self.numberOfSymbolsCoarse] #sortedByPeRatio = sorted(fine, key=lambda x: x.ValuationRatios.PERatio, reverse=True) #Sort descending by P/E ratio #return [x.Symbol for x in sortedByPeRatio[:self.__numberOfSymbolsFine]] #Take the top 'NumberOfSymbolsFine' entries from our sorted collection #f_filter = [x for x in fine if x.MarketCap < 5000000000] #return [x.Symbol for x in f_filter]