Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 |
#This is a Template of dynamic stock selection. #You can try your own fundamental factor and ranking method by editing the CoarseSelectionFunction and FineSelectionFunction from System.Collections.Generic import List from QuantConnect.Data.UniverseSelection import * class BasicTemplateAlgorithm(QCAlgorithm): def __init__(self): # set the flag for rebalance self.reb = 1 # Number of stocks to pass CoarseSelection process self.num_coarse = 50 # Number of stocks to long/short self.num_fine = 20 self.symbols = None self.first_month = 0 def Initialize(self): self.SetCash(100000) self.SetStartDate(2015,1,1) # if not specified, the Backtesting EndDate would be today self.SetEndDate(2015,8,1) self.spy = self.AddEquity("SPY", Resolution.Daily).Symbol self.UniverseSettings.Resolution = Resolution.Daily self.AddUniverse(self.CoarseSelectionFunction,self.FineSelectionFunction) # Schedule the rebalance function to execute at the begining of each month self.Schedule.On(self.DateRules.MonthStart(self.spy), self.TimeRules.AfterMarketOpen(self.spy,5), Action(self.Rebalance)) def CoarseSelectionFunction(self, coarse): # Attempt to only try rebalance quarterly on the 1st day of the month #today = self.Time #self.Log("Day = {} Month = {}".format(today.day,today.month)) if self.reb != 1: return CoarseWithFundamental = [x for x in coarse if x.HasFundamentalData] sortedByDollarVolume = sorted(CoarseWithFundamental, key=lambda x: x.DollarVolume, reverse=True) #result = [ x.Symbol for x in sortedByDollarVolume[:self.__numberOfSymbols] ] result = [ x.Symbol for x in sortedByDollarVolume[:self.num_coarse] ] self.universe = result return self.universe def FineSelectionFunction(self, fine): # return null list if it's not time to rebalance if self.reb != 1: return self.reb = 0 # drop stocks which don't have the information we need. # you can try replacing those factor with your own factors here filtered_fine = [x for x in fine if x.ValuationRatios.PriceChange1M and x.ValuationRatios.PERatio] self.Log('remained to select %d'%(len(filtered_fine))) # rank stocks by two factors. sortedByfactor1 = sorted(filtered_fine, key=lambda x: x.ValuationRatios.PriceChange1M, reverse=False) sortedByfactor2 = sorted(filtered_fine, key=lambda x: x.ValuationRatios.PERatio, reverse=False) stock_dict = {} # assign a score to each stock, you can also change the rule of scoring here. for i,ele in enumerate(sortedByfactor1): rank1 = i rank2 = sortedByfactor2.index(ele) score = sum([rank1*0.5,rank2*0.5]) stock_dict[ele] = score # sort the stocks by their scores self.sorted_stock = sorted(stock_dict.items(), key=lambda d:d[1],reverse=False) sorted_symbol = [x[0] for x in self.sorted_stock] # sort the top stocks into the long_list and the bottom ones into the short_list self.longs = [x.Symbol for x in sorted_symbol[:self.num_fine]] #topFine = self.long #self.universe = [ x.Symbol for x in topFine ] #self.universe = self.long #return self.universe #return [i.Symbol for i in (self.long)] return self.longs #else: # return [] def OnData(self, data): pass def Rebalance(self): if self.first_month == 0: self.first_month += 1 return # if this month the stock are not going to be long/short, liquidate it. for i in self.Portfolio.Values: if (i.Invested) and (i.Symbol not in self.longs): self.Liquidate(i.Symbol) # Alternatively, you can liquidate all the stocks at the end of each month. # Which method to choose depends on your investment philosiphy # if you prefer to realized the gain/loss each month, you can choose this method. #self.Liquidate() # Assign each stock equally. Alternatively you can design your own portfolio construction method for i in self.longs: self.SetHoldings(i,0.99/self.num_fine) self.reb = 1