Overall Statistics |
Total Trades 764 Average Win 0.73% Average Loss -0.39% Compounding Annual Return 8.255% Drawdown 41.500% Expectancy 1.057 Net Profit 436.208% Sharpe Ratio 0.618 Probabilistic Sharpe Ratio 1.797% Loss Rate 29% Win Rate 71% Profit-Loss Ratio 1.88 Alpha 0.077 Beta -0.023 Annual Standard Deviation 0.122 Annual Variance 0.015 Information Ratio 0.023 Tracking Error 0.218 Treynor Ratio -3.317 Total Fees $2677.14 |
from QuantConnect import Resolution from QuantConnect.Algorithm import QCAlgorithm class NCAVsimple(QCAlgorithm): def Initialize(self): #rebalancing should occur in July self.SetStartDate(2000, 1, 1) self.SetCash(100000) self.UniverseSettings.Resolution = Resolution.Daily self.filtered_fine = None self.filtered_coarse = None self.symbol = self.AddEquity('SPY', Resolution.Daily).Symbol # self.SetSecurityInitializer(lambda x: x.SetMarketPrice(self.GetLastKnownPrice(x))) self.yearly_rebalance = False self.AddUniverse(self.CoarseSelectionFunction,self.FineSelectionFunction) self.Schedule.On(self.DateRules.MonthEnd(self.symbol), self.TimeRules.AfterMarketOpen(self.symbol), self.rebalance) def CoarseSelectionFunction(self, coarse): if self.yearly_rebalance: # drop stocks which have no fundamental data or have low price self.filtered_coarse = [x.Symbol for x in coarse if (x.HasFundamentalData) and x.Market == 'usa'] return self.filtered_coarse else: return Universe.Unchanged def FineSelectionFunction(self, fine): if self.yearly_rebalance: #calculate the NCAV/MV and add the property to fine universe object #filters out the companies in the financial sector as suggested fine = [x for x in fine if (float(x.FinancialStatements.BalanceSheet.CurrentAssets.Value) > 0) and (float(x.EarningReports.BasicAverageShares.Value) > 0) and (float(x.FinancialStatements.BalanceSheet.CurrentLiabilities.Value) > 0) and (float(x.MarketCap) > 0) # This indicator will denote which one of the six industry data collection templates applies to the company. # Each industry data collection template includes data elements that are commonly reported by companies in that industry. # N=Normal (Manufacturing), M=Mining, U=Utility, T=Transportation, B=Bank, I=Insurance and (x.CompanyReference.IndustryTemplateCode!="B") and (x.CompanyReference.IndustryTemplateCode!="I")] fine = sorted(fine, key = lambda x:x.MarketCap, reverse=True) self.Debug("fine len: " + str(len(fine))) for i in fine: #calculates the net current asset value per share self.Debug(i.Symbol) total_liabilities = i.FinancialStatements.BalanceSheet.TotalLiabilitiesAsReported.TwelveMonths current_assets = i.FinancialStatements.BalanceSheet.CurrentAssets.TwelveMonths i.ncav = (current_assets - total_liabilities)/float(i.MarketCap) if i.ncav > 1.5: self.Debug("-total_liabilities: " + str(total_liabilities)) self.Debug("-current_assets: " + str(current_assets)) self.Debug("-market_cap: " + str(i.MarketCap)) self.Debug("-ncav: " + str(i.ncav)) # keeps all symbols that have a NCAV/MV higher than 1.5 # sorted_fine = sorted(fine, lambda x: x.ncav) self.filtered_fine = [i.Symbol for i in fine if (i.ncav > 1.5)] return self.filtered_fine[:25] else: return [] def rebalance(self): #yearly rebalance if self.Time.month == 7: self.Debug("Rebalance" + str(self.Time)) self.yearly_rebalance = True def OnData(self, data): if not self.yearly_rebalance: return if self.filtered_fine: stocks_invested = [x.Key for x in self.Portfolio] for i in stocks_invested: #liquidate the stocks not in the filtered NCAV/MV list if i not in self.filtered_fine: self.Liquidate(i) #purchase the stocks in the list elif i in self.filtered_fine: self.SetHoldings(i, 1/len(self.filtered_fine)) self.yearly_rebalance = False