Overall Statistics |
Total Trades 3015 Average Win 0.03% Average Loss -0.02% Compounding Annual Return 0.260% Drawdown 9.100% Expectancy -0.078 Net Profit 1.462% Sharpe Ratio 0.083 Loss Rate 65% Win Rate 35% Profit-Loss Ratio 1.63 Alpha -0.027 Beta 1.674 Annual Standard Deviation 0.036 Annual Variance 0.001 Information Ratio -0.416 Tracking Error 0.036 Treynor Ratio 0.002 Total Fees $3018.20 |
class TwelveMonthCycle(QCAlgorithm): def Initialize(self): self.SetStartDate(2013, 1, 1) self.SetEndDate(2018, 8, 1) self.SetCash(100000) self.AddEquity("SPY", Resolution.Daily) self.Schedule.On(self.DateRules.MonthStart("SPY"), self.TimeRules.AfterMarketOpen("SPY"), self.Rebalance) self.monthly_rebalance = False self.filtered_fine = None self.UniverseSettings.Resolution = Resolution.Daily self.AddUniverse(self.CoarseSelectionFunction, self.FineSelectionFunction) def CoarseSelectionFunction(self, coarse): if self.monthly_rebalance: coarse = [x for x in coarse if (x.HasFundamentalData) and (x.Market == "usa")] return [i.Symbol for i in coarse] else: return [] def FineSelectionFunction(self, fine): if self.monthly_rebalance: fine =[i for i in fine if ((i.SecurityReference.ExchangeId == "NYS") or (i.SecurityReference.ExchangeId == "ASE"))] self.filtered_fine = [] for i in fine: i.MarketCap = float(i.EarningReports.BasicAverageShares.TwelveMonths * (i.EarningReports.BasicEPS.TwelveMonths*i.ValuationRatios.PERatio)) history_start = self.History([i.Symbol], TimeSpan.FromDays(365)) history_end = self.History([i.Symbol],TimeSpan.FromDays(335)) if not history_start.empty and not history_end.empty: i.Returns = float(history_end.iloc[0]["close"] - history_start.iloc[0]["close"]) self.filtered_fine.append(i) size = int(len(fine)*.3) self.filtered_fine = sorted(self.filtered_fine, key = lambda x: x.MarketCap, reverse=True) self.filtered_fine = self.filtered_fine[:size] self.filtered_fine = sorted(self.filtered_fine, key = lambda x: x.Returns, reverse=True) symbols = [i.Symbol for i in self.filtered_fine] self.filtered_fine = symbols return symbols else: return [] def Rebalance(self): self.monthly_rebalance = True def OnData(self, data): if not (self.monthly_rebalance): return if not (self.filtered_fine): return self.monthly_rebalance = False portfolio_size = int(len(self.filtered_fine)/10) short_stocks = self.filtered_fine[-portfolio_size:] long_stocks = self.filtered_fine[:portfolio_size] stocks_invested = [x.Key for x in self.Portfolio] for i in stocks_invested: #liquidate the stocks not in the filtered balance sheet accrual list if i not in self.filtered_fine: self.Liquidate(i) #long the stocks in the list elif i in long_stocks: self.SetHoldings(i, 1/(portfolio_size*2)) #short the stocks in the list elif i in short_stocks: self.SetHoldings(i,-1/(portfolio_size*2))