Overall Statistics |
Total Trades 144 Average Win 0.55% Average Loss -0.58% Compounding Annual Return 27.398% Drawdown 20.000% Expectancy 0.187 Net Profit 27.398% Sharpe Ratio 1.096 Probabilistic Sharpe Ratio 49.903% Loss Rate 39% Win Rate 61% Profit-Loss Ratio 0.94 Alpha 0.077 Beta 1.1 Annual Standard Deviation 0.185 Annual Variance 0.034 Information Ratio 1.022 Tracking Error 0.087 Treynor Ratio 0.184 Total Fees $239.28 Estimated Strategy Capacity $780000.00 Lowest Capacity Asset HOL TYJB6RKZ4JTX |
MAX_POSITIONS = 20 REBALANCE_PERIOD = 20 class DataTesting(QCAlgorithm): def Initialize(self): self.SetStartDate(2010, 1, 1) self.SetEndDate(2010, 12, 31) self.SetCash(100000) self.UniverseSettings.Resolution = Resolution.Minute self.AddUniverse(self.CoarseFilter, self.FineFilter) self.rebalance = 0 self.buy = [] self.sell = [] def CoarseFilter(self, coarse): if self.rebalance and self.rebalance <= REBALANCE_PERIOD: self.rebalance += 1 return Universe.Unchanged self.rebalance = 1 #filtered = [x for x in coarse if x.HasFundamentalData] #filtered = [x for x in filtered if float(x.AdjustedPrice) > 5] #filtered = [x.Symbol for x in filtered] filtered = [x.Symbol for x in coarse if x.HasFundamentalData and (x.AdjustedPrice > 5.0)] return filtered def FineFilter(self, fine): filtered = list(filter(self.FineFundamentalFilter, fine)) return self.FineSort(filtered)[:MAX_POSITIONS] def FineFundamentalFilter(self, security): eps3m = security.EarningRatios.DilutedEPSGrowth.ThreeMonths > 0 eps1y = security.EarningRatios.DilutedEPSGrowth.OneYear > 0 fcf3m = security.FinancialStatements.CashFlowStatement.FreeCashFlow.ThreeMonths > 0 fcf1y = security.FinancialStatements.CashFlowStatement.FreeCashFlow.TwelveMonths > 0 roe3m = security.OperationRatios.ROE.ThreeMonths > 0 roe1y = security.OperationRatios.ROE.OneYear > 0 return eps3m and eps1y and fcf3m and fcf1y and roe3m and roe1y def FineSort(self, fine): ranked = {} ranks = { 'earnings_growth': [x.Symbol for x in sorted(fine, key=lambda x: (x.EarningRatios.DilutedEPSGrowth.ThreeMonths + x.EarningRatios.DilutedEPSGrowth.OneYear + x.EarningRatios.DilutedEPSGrowth.ThreeYears) / 3 )], 'revenue_growth': [x.Symbol for x in sorted(fine, key=lambda x: (x.OperationRatios.RevenueGrowth.ThreeMonths + x.OperationRatios.RevenueGrowth.OneYear + x.OperationRatios.RevenueGrowth.ThreeYears) / 3 )], 'book_growth': [x.Symbol for x in sorted(fine, key=lambda x: (x.EarningRatios.BookValuePerShareGrowth.ThreeMonths + x.EarningRatios.BookValuePerShareGrowth.OneYear + x.EarningRatios.BookValuePerShareGrowth.ThreeYears) / 3 )], 'fcf_growth': [x.Symbol for x in sorted(fine, key=lambda x: (x.EarningRatios.FCFPerShareGrowth.ThreeMonths + x.EarningRatios.FCFPerShareGrowth.OneYear + x.EarningRatios.FCFPerShareGrowth.ThreeYears) / 3 )] } for security in fine: symbol = security.Symbol ranked[symbol] = 0 for key, sort in ranks.items(): ranked[symbol] += (sort.index(symbol) + 1) #ranked = dict(sorted(ranked.items(), key=lambda x: x[1], reverse=True)) #ranked = [symbol for symbol in ranked] ranked = [symbol for symbol, rank in sorted(ranked.items(), key=lambda t: t[1], reverse=True)] return ranked def OnSecuritiesChanged(self, changes): for added in changes.AddedSecurities: self.buy.append(added.Symbol) for removed in changes.RemovedSecurities: self.sell.append(removed.Symbol) def OnData(self, data): #sell = self.sell[:] #buy = self.buy[:] #if len(sell) > 0: # for symbol in sell: # if data.ContainsKey(symbol): # self.sell.remove(symbol) # self.Liquidate(symbol) #if len(buy) > 0: # for symbol in buy: # if data.ContainsKey(symbol): # self.buy.remove(symbol) # self.SetHoldings(symbol, 1 / MAX_POSITIONS) for symbol in [*self.sell]: self.sell.remove(symbol) self.Liquidate(symbol) for symbol in [*self.buy]: if data.ContainsKey(symbol) and data[symbol] is not None: self.buy.remove(symbol) self.SetHoldings(symbol, 1 / MAX_POSITIONS)