Overall Statistics |
Total Trades 2171 Average Win 0.09% Average Loss -0.11% Compounding Annual Return 0.564% Drawdown 17.900% Expectancy -0.020 Net Profit 3.189% Sharpe Ratio 0.101 Probabilistic Sharpe Ratio 0.529% Loss Rate 45% Win Rate 55% Profit-Loss Ratio 0.78 Alpha 0.027 Beta -0.202 Annual Standard Deviation 0.052 Annual Variance 0.003 Information Ratio -0.779 Tracking Error 0.132 Treynor Ratio -0.026 Total Fees $2171.00 Estimated Strategy Capacity $820000.00 Lowest Capacity Asset CEA R735QTJ8XC9X |
#region imports from AlgorithmImports import * #endregion class TwelveMonthCycle(QCAlgorithm): def Initialize(self): self.SetStartDate(2013, 1, 1) self.SetEndDate(2018, 8, 1) self.SetCash(100000) self.UniverseSettings.Resolution = Resolution.Daily self.AddUniverse(self.CoarseSelectionFunction, self.FineSelectionFunction) 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 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: 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)[:size] self.filtered_fine = sorted(self.filtered_fine, key = lambda x: x.Returns, reverse=True) self.filtered_fine = [i.Symbol for i in self.filtered_fine] return self.filtered_fine 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))