Overall Statistics |
Total Orders 724 Average Win 0.88% Average Loss -0.92% Compounding Annual Return 10.358% Drawdown 50.400% Expectancy 0.104 Start Equity 100000 End Equity 121822.70 Net Profit 21.823% Sharpe Ratio 0.394 Sortino Ratio 0.46 Probabilistic Sharpe Ratio 14.364% Loss Rate 44% Win Rate 56% Profit-Loss Ratio 0.96 Alpha -0.054 Beta 1.238 Annual Standard Deviation 0.422 Annual Variance 0.178 Information Ratio -0.036 Tracking Error 0.336 Treynor Ratio 0.134 Total Fees $875.52 Estimated Strategy Capacity $1200000.00 Lowest Capacity Asset HOL XI5N30EK4UP1 Portfolio Turnover 4.00% |
# region imports # setting up the universe of stocks # keep mind of the selection bias # Trading Strategy: stock cap stocks have outperformed large cap stocks; 200 most liquid stocks and then take bottom 10 # Rebalance every month from AlgorithmImports import * # endregion class SwimmingAsparagusTermite(QCAlgorithm): def Initialize(self): self.SetStartDate(2020, 1, 1) # Set Start Date self.SetEndDate(2022, 1, 1) self.SetCash(100000) # rebalance time = minimum of set date self.rebalanceTime = datetime.min self.activeStocks = set() # add to universe of stock with coarse filter and fine filter self.AddUniverse(self.CoarseFilter, self.FineFilter) self.UniverseSettings.Resolution = Resolution.Hour self.portfolioTargets = [] def CoarseFilter(self, coarse): # no need to rebalance within 1 month if self.Time <= self.rebalanceTime: return self.Universe.Unchanged self.rebalanceTime = self.Time + timedelta(30) # add one month ahead # filter stocks by dollarvolume sortedByDollarVolume = sorted(coarse, key = lambda x: x.DollarVolume, reverse = True) return [x.Symbol for x in sortedByDollarVolume if x.Price > 10 and x.HasFundamentalData][:200] def FineFilter(self, fine): sortedByPE = sorted(fine, key = lambda x: x.MarketCap) return [x.Symbol for x in sortedByPE if x.MarketCap > 0][:20] def OnSecuritiesChanged(self, changes): for x in changes.RemovedSecurities: self.Liquidate(x.Symbol) self.activeStocks.remove(x.Symbol) for x in changes.AddedSecurities: self.activeStocks.add(x.Symbol) self.portfolioTargets = [PortfolioTarget(symbol, 1/len(self.activeStocks)) for symbol in self.activeStocks] def OnData(self, data: Slice): if self.portfolioTargets == []: return for symbol in self.activeStocks: if symbol not in data: return self.SetHoldings(self.portfolioTargets) self.portfolioTargets = []