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]