The net current asset value per share (NCAV/MV) is a key metric for value investors. NCAV/MV is the balance sheet current assets minus all the firm's (current and long-term) liabilities divided by the number of shares outstanding. This rule forms portfolios filled with stocks with market capitalization lower than the amount of cash plus inventories they own. A lot of these stocks are so cheap because the companies are in distress and will eventually go bankrupt. But the rest of the stocks bought with an extreme discount statistically gain more, and the overall portfolio return is highly positive.

This algorithm was derived from Quantpedia, where it was originally meant for an investment universe of the London Exchange. For users interested in seeing more strategies like this check out the Strategy Library.

The first step is the coarse and fine universe selection. Using coarse selection, we create an investment universe with stocks that have fundamental data and a price greater than $5.

self.filtered_coarse = [x.Symbol for x in coarse if (x.HasFundamentalData) and (float(x.AdjustedPrice) > 5)]

During fine universe selection, we take the stocks and calculate their net capital asset value per share. The stocks whose net capital asset value per share is above 1.5 are chosen for the portfolio.

def FineSelectionFunction(self, fine):
   if self.yearly_rebalance:
       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.FinancialStatements.BalanceSheet.TotalNonCurrentLiabilitiesNetMinorityInterest.Value) > 0)
                                   and (x.CompanyReference.IndustryTemplateCode!="B")
                                   and (x.CompanyReference.IndustryTemplateCode!="I")]
       for i in fine:
           total_liabilities = float(i.FinancialStatements.BalanceSheet.CurrentLiabilities.Value)+float(i.FinancialStatements.BalanceSheet.TotalNonCurrentLiabilitiesNetMinorityInterest.Value)
           i.ncav = (float(i.FinancialStatements.BalanceSheet.CurrentAssets.Value) - total_liabilities)/float(i.EarningReports.BasicAverageShares.Value)
       self.filtered_fine = [i.Symbol for i in fine if (i.ncav > 1.5)]
       return self.filtered_fine
   else:
       return []

In OnData(), we buy all the stocks in the filtered list. The portfolio is rebalanced every year at the start of July.