Overall Statistics
Total Trades
849
Average Win
0.18%
Average Loss
-0.13%
Compounding Annual Return
-10.979%
Drawdown
8.400%
Expectancy
-0.047
Net Profit
-2.858%
Sharpe Ratio
-0.498
Probabilistic Sharpe Ratio
20.825%
Loss Rate
60%
Win Rate
40%
Profit-Loss Ratio
1.41
Alpha
-0.058
Beta
-0.091
Annual Standard Deviation
0.164
Annual Variance
0.027
Information Ratio
-1.619
Tracking Error
0.214
Treynor Ratio
0.904
Total Fees
$1378.70
Estimated Strategy Capacity
$1300.00
Lowest Capacity Asset
WVFC R735QTJ8XC9X
forLong = []
forShort = []
class UglyRedOrangeChinchilla(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2020, 12, 1)  
        self.SetEndDate(2021, 3, 1) 
        self.SetCash(100000)  
        self.SetBenchmark("SPY")

        self.UniverseSettings.Resolution = Resolution.Daily
        self.AddUniverseSelection(
            FineFundamentalUniverseSelectionModel(self.SelectCoarse, 
                                                    self.SelectFine))
            
        self.AddAlpha(MyAlphaModel())
        self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
        self.SetExecution(ImmediateExecutionModel())
    
    def SelectCoarse(self, coarse):
        
        hasFundamentalData = [c for c in coarse if c.HasFundamentalData]
        filteredByPrice = [c.Symbol for c in hasFundamentalData if c.Price > 10]
        
        return filteredByPrice

    def SelectFine(self, fine):
        sortedByPERatio = sorted(fine, 
                            key=lambda f: f.ValuationRatios.PERatio1YearHigh, 
                            reverse=False)
        self.forLong = [f.Symbol for f in sortedByPERatio[:10]]
        self.forShort = [f.Symbol for f in sortedByPERatio[-10:]]
        return self.forShort + self.forLong
    
class SymbolData:
    def __init__(self,security):
        self.symbol = security.Symbol
        self.peRatio = security.Fundamentals.ValuationRatios.PERatio1YearHigh
        
class MyAlphaModel:
        def __init__(self):
            self.dataBySymbol = {}
            
        def Update(self, algorithm, slice):
            insights = []
            for symbol in self.forLong:
                if symbol in slice.Bars:
                    insights.append(Insight.Price(symbol, timedelta(28), InsightDirection.Up))
            for symbol in self.forShort:
                if symbol in slice.Bars:
                    insights.append(Insight.Price(symbol, timedelta(28), InsightDirection.Down))
            
            return insights
    
        def OnSecuritiesChanged(self, algorithm, changes):
            self.changes = changes
            self.forLong = []
            self.forShort = []
            for security in self.changes.RemovedSecurities:
                if security.Symbol in self.dataBySymbol:
                    self.dataBySymbol.pop(security.Symbol)
                
                    
            algorithm.Debug(str(len(self.changes.RemovedSecurities)+len(self.changes.AddedSecurities)))
            for security in self.changes.AddedSecurities:
               
               if security.Symbol not in self.dataBySymbol:
                   self.dataBySymbol[security.Symbol] = SymbolData(security)
            selected = list(self.dataBySymbol.values())
            sortedByPE = sorted(selected,key = lambda x : x.peRatio)

            self.forLong = [x.symbol for x in sortedByPE[:10]]
            self.forShort = [x.symbol for x in sortedByPE[-10:]]