Net Current Asset Value Effect Algorithm

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
       return []

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

Update Backtest

Update Backtest


The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


This discussion is closed