Overall Statistics |
Total Trades 490 Average Win 0.82% Average Loss -0.67% Compounding Annual Return 18.445% Drawdown 32.700% Expectancy 0.283 Net Profit 66.244% Sharpe Ratio 0.707 Probabilistic Sharpe Ratio 24.026% Loss Rate 42% Win Rate 58% Profit-Loss Ratio 1.22 Alpha 0.044 Beta 1.227 Annual Standard Deviation 0.212 Annual Variance 0.045 Information Ratio 0.61 Tracking Error 0.104 Treynor Ratio 0.122 Total Fees $907.10 Estimated Strategy Capacity $110000.00 Lowest Capacity Asset CVCO SPYCIDBUES85 |
MAX_POSITIONS = 20 REBALANCE_PERIOD = 20 class DataTesting(QCAlgorithm): def Initialize(self): self.SetStartDate(2010, 1, 1) self.SetEndDate(2012, 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] 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] 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)