Overall Statistics
Total Trades
155
Average Win
0.17%
Average Loss
-0.12%
Compounding Annual Return
19.901%
Drawdown
5.000%
Expectancy
0.519
Net Profit
4.319%
Sharpe Ratio
1.762
Probabilistic Sharpe Ratio
61.562%
Loss Rate
36%
Win Rate
64%
Profit-Loss Ratio
1.37
Alpha
0
Beta
0
Annual Standard Deviation
0.115
Annual Variance
0.013
Information Ratio
1.762
Tracking Error
0.115
Treynor Ratio
0
Total Fees
$155.00
Estimated Strategy Capacity
$180000000.00
class CrawlingRedDog(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2020, 10, 8)
        self.SetEndDate(2020, 12, 31)
        self.SetCash(100000)  # Set Strategy Cash
        self.AddUniverse(self.CoarseSelectionFilter)
        self.UniverseSettings.Resolution = Resolution.Daily
        self.averages = {}
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage)


    def CoarseSelectionFilter(self, coarse):
        selected = []
        coarse = sorted(coarse, key=lambda c: c.DollarVolume, reverse=True)  
        coarse = [c for c in coarse if c.Price > 10][:20]

        for coar in coarse:  
            symbol = coar.Symbol
            
            if symbol not in self.averages:
                history = self.History(symbol, 200, Resolution.Daily)
                self.averages[symbol] = SelectionData(history) 

            self.averages[symbol].update(self.Time, coar.AdjustedPrice)
            
            if  self.averages[symbol].is_ready(): 
                    if self.averages[symbol].rsi_max.Current.Value < 66:
                        selected.append(symbol)
                    
        return selected
                    
    def OnSecuritiesChanged(self, changes):
        self.changes = changes
        
        for security in self.changes.RemovedSecurities:
            if security.Invested:
                self.Liquidate(security.Symbol)
        
        for security in self.changes.AddedSecurities:
            self.SetHoldings(security.Symbol, .05)

        
class SelectionData():
    def __init__(self, history):
        self.rsi = RelativeStrengthIndex(20, Resolution.Daily)
        self.rsi_max = IndicatorExtensions.MAX(self.rsi, 5)
        
        for data in history.itertuples():
            time = data.Index[1]
            close = data.close
            self.rsi.Update(time, close)
            
    def is_ready(self):
        return self.rsi.IsReady
        
    def update (self, time, price):
        self.rsi.Update(time, price)