Overall Statistics
Total Trades
8
Average Win
0.37%
Average Loss
-1.03%
Compounding Annual Return
-0.029%
Drawdown
2.600%
Expectancy
-0.323
Net Profit
-0.091%
Sharpe Ratio
-0.013
Probabilistic Sharpe Ratio
1.512%
Loss Rate
50%
Win Rate
50%
Profit-Loss Ratio
0.35
Alpha
-0
Beta
0.015
Annual Standard Deviation
0.011
Annual Variance
0
Information Ratio
0.014
Tracking Error
0.169
Treynor Ratio
-0.009
Total Fees
$8.00
Estimated Strategy Capacity
$390000.00
Lowest Capacity Asset
TRY R735QTJ8XC9X
from QuantConnect.Data.UniverseSelection import *


class PriceEarningsAnamoly(QCAlgorithm):

    def Initialize(self):

        self.SetStartDate(1999, 1, 2)   
        self.SetWarmUp(timedelta(7)) # Warm up 7 days of data.

        self.SetEndDate(2002, 3, 1)         
        self.SetCash(100000)
        self.SetBenchmark("SPY")
        
        self.UniverseSettings.Resolution = Resolution.Daily
        self.UniverseSettings.Leverage = 1.0 
        self.UniverseSettings.MinimumTimeInUniverse = timedelta(days=365)
        self.symbols = []
        
        # record the year that have passed since the algorithm starts
        self.month = -1
        self._ratioCoarseFilter = .9
        self._NumStocksInPortfolio = 2
        
        self.AddUniverse(self.CoarseSelectionFunction, self.FineSelectionFunction)
        
        
    def CoarseSelectionFunction(self, coarse):
        
        if self.Time.month == self.month:
            return self.symbols
        
        # drop stocks which have no fundamental data or have no price
        CoarseWithFundamental = [x for x in coarse 
                                if x.HasFundamentalData and x.Price > 0]
                                
        sortedByDollarVolume = sorted(CoarseWithFundamental, key=lambda x: x.DollarVolume, reverse=True) 
        coarse = [i.Symbol for i in sortedByDollarVolume[:int(len(sortedByDollarVolume)*self._ratioCoarseFilter)]]

        return coarse
        
        
    def FineSelectionFunction(self, fine):
        
        if self.Time.month == self.month:
            return self.symbols
    
        self.month = self.Time.month
        
        self.Debug(f"Use ROE")

        fine = [x for x in fine if (self.Time - x.SecurityReference.IPODate).days > 180
                    and x.MarketCap > 5e8]
                                
        sortedPERatio = sorted(fine, key=lambda x: x.OperationRatios.ROE.OneYear, reverse=True)
        
        self.symbols = [i.Symbol for i in sortedPERatio[:self._NumStocksInPortfolio]]
        
        
        return self.symbols
            
            
    def OnSecuritiesChanged(self, change):
        
        # liquidate securities that removed from the universe
        for security in change.RemovedSecurities:
            if self.Portfolio[security.Symbol].Invested:
                self.Liquidate(security.Symbol)

        count = len(change.AddedSecurities)

        # evenly invest on securities that newly added to the universe
        for security in change.AddedSecurities:
            self.SetHoldings(security.Symbol, .8/(self._NumStocksInPortfolio*12))