Overall Statistics
Total Trades
390
Average Win
0.24%
Average Loss
-0.21%
Compounding Annual Return
18.615%
Drawdown
5.300%
Expectancy
0.416
Net Profit
21.933%
Sharpe Ratio
1.835
Loss Rate
33%
Win Rate
67%
Profit-Loss Ratio
1.12
Alpha
0.129
Beta
1.967
Annual Standard Deviation
0.09
Annual Variance
0.008
Information Ratio
1.625
Tracking Error
0.09
Treynor Ratio
0.084
Total Fees
$487.23
# Strategy : Rebalancing Portfolio on Day 1 of the Every Month based on the fundamental data and liquidity of stock
# Backtest Result : Creative Red Butterfly


import numpy as np
import datetime as dt
from datetime import datetime,timedelta


class QCAlgorithm(QCAlgorithm):
    
    
    def Initialize(self):
        
        # Backtest Parameters
        self.SetStartDate(2013,12,31)
        self.SetEndDate(2015,3,1)
        self.SetCash(100000.00)
        
        # Setting Daily Resolution for all Securities in Universe.
        self.UniverseSettings.Resolution = Resolution.Daily
        
        #Adding Universe based on the defined filters
        self.AddUniverse(self.MyCoarseUniverse,self.MyFineUniverse)
        
        # Brokerage Model 
        self.SetBrokerageModel(BrokerageName.Default, AccountType.Cash)
        self.SetTimeZone(TimeZones.NewYork)
        
        #reference check for the developing new portfolio while rebalancing whether securities has changed 
        self._changes = None
        
        # Schedule Rebalancing of Portfolio on Starting of the Month at 10 AM.
        self.Schedule.On(self.DateRules.MonthStart(), self.TimeRules.At(10, 00), Action(self.Rebalance))
         
        
        
    # define first filter which  will filter the stocks based on the Dollervolume and if it has fundamental deta available 
    # so that we can run those stocks through second filter.
    def MyCoarseUniverse(self,coarse):
        
        for x in coarse: 
            
            # sorting of stocks based on dollervolume in descending order
            sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
            
            # filter if the stock has dollarvolume of more than 1000000 and has fundamentaldata
            filtered = [ x.Symbol for x in sortedByDollarVolume if x.DollarVolume > 1000000 and x.HasFundamentalData == True]
            
            #return first 1000 such stocks that we will feed in our second "fine" filter 
            return filtered[:1000]      
            
            
            
    # The output of the coarse function will in this function for second filter
    def MyFineUniverse(self,fine):
        
        #sort stocks based on the EV / EBITDA in descending order 
        sortedByEVRatio = sorted(fine, key=lambda x: x.ValuationRatios.EVToEBITDA, reverse=True)
        
        
        # filter the stock list which has BookValue per share less than 1. ( These stocks's potential has not been realised due to market sentiments)
        filtered = [x.Symbol for x in sortedByEVRatio if x.ValuationRatios.BookValuePerShare <= 1] 
        
        return filtered[:50]
          
           
           
            
            
    def OnSecuritiesChanged(self, changes):
        
        # changes in our security Universe will change the value of our reference variable defined in Initialize. 
        # It will have the information of addedsecurity and removed security which we will use to buy and liquidate security from our existing portfolio to rebalance.
        self._changes = changes
        
    
    # ScheduledOn will triger this function on month start as defined in Initialize
    def Rebalance(self):
        
        # check the day of datetime object if it is first day of the month if "No", do nothing and return
        if self.Time.day != 1 : 
            
            return self.Debug(" No Need to Rebalance, Month :" + str(self.Time.month)) 
         
            
        else :  
            
            self.Debug(" Portfolio will be Rebalanced , Month :" + str(self.Time.month) + "Day :" + str(self.Time.day))
            
            # OnSecurityChanged will change the value of reference variable through which we get to know if there is change in our Universe
            #If the variable is "None" that means no security has been added and removed from our universe. It will keep our portfolio as it is.
            if not self._changes is None : 
                
                # give equal weight to security that has been added in the universe
                if len(self._changes.AddedSecurities) == 0:
                    weightage = 0.5
                else :
                    weightage = 1/len(self._changes.AddedSecurities)
                    
                # liquidate portfolio    
                if self.Portfolio.Invested:        
                    self.Liquidate()
                
                # invest in added securities based on predetermined weightage   
                for x in self._changes.AddedSecurities:
                    
                    self.Debug("Security Weightage : " + str(weightage))
                    self.SetHoldings(x.Symbol,weightage)
                    
                    self.Debug("Portfolio Rebalanced")
                    
                    # change the value of variable again to None.
                    self._changes = None