Overall Statistics
Total Trades
4322
Average Win
0.04%
Average Loss
-0.01%
Compounding Annual Return
10.017%
Drawdown
41.900%
Expectancy
3.583
Net Profit
161.882%
Sharpe Ratio
0.568
Loss Rate
13%
Win Rate
87%
Profit-Loss Ratio
4.24
Alpha
0.255
Beta
-9.922
Annual Standard Deviation
0.161
Annual Variance
0.026
Information Ratio
0.466
Tracking Error
0.161
Treynor Ratio
-0.009
Total Fees
$4954.33
class NetCurrentAssetValue(QCAlgorithm):

    def Initialize(self):
        #rebalancing should occur in July
        self.SetStartDate(2008,6,15)  #Set Start Date
        self.SetEndDate(2018,7,15)    #Set End Date
        self.SetCash(1000000)           #Set Strategy Cash
        self.UniverseSettings.Resolution = Resolution.Minute
        self.filtered_fine = None
        self.filtered_coarse = None
        self.AddUniverse(self.CoarseSelectionFunction,self.FineSelectionFunction)
        self.AddEquity("SPY", Resolution.Hour)
        #monthly scheduled event but will only rebalance once a year
        self.Schedule.On(self.DateRules.MonthStart("SPY"), self.TimeRules.At(23, 0), self.rebalance)
        self.months = -1
        self.yearly_rebalance = False
        
    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 (float(x.AdjustedPrice) > 5)]
            return self.filtered_coarse
        else: 
            return []      
    
    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.FinancialStatements.BalanceSheet.TotalNonCurrentLiabilitiesNetMinorityInterest.Value) > 0)
                                    and (x.CompanyReference.IndustryTemplateCode!="B")
                                    and (x.CompanyReference.IndustryTemplateCode!="I")]
            for i in fine:
                #calculates the net current asset value per share
                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)
                
            #keeps all symbols that have a NCAV/MV higher than 1.5
            self.filtered_fine = [i.Symbol for i in fine if (i.ncav > 1.5)]
            return self.filtered_fine
        else:
            return []
    
    def rebalance(self):
        #yearly rebalance
        self.months+=1
        if self.months%12 == 0:
            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