Overall Statistics
Total Trades
2406
Average Win
0.58%
Average Loss
-0.63%
Compounding Annual Return
6.619%
Drawdown
24.900%
Expectancy
0.049
Net Profit
37.823%
Sharpe Ratio
0.396
Probabilistic Sharpe Ratio
6.521%
Loss Rate
45%
Win Rate
55%
Profit-Loss Ratio
0.92
Alpha
0.084
Beta
-0.093
Annual Standard Deviation
0.181
Annual Variance
0.033
Information Ratio
-0.239
Tracking Error
0.24
Treynor Ratio
-0.773
Total Fees
$0.00
Estimated Strategy Capacity
$15000000.00
Lowest Capacity Asset
ABBV VCY032R250MD
class EMAMomentumUniverse(QCAlgorithm):
    
    def Initialize(self):
        self.SetStartDate(2010, 1, 7)
        self.SetEndDate(2015, 1, 7)
        self.SetCash(100000)
        self.UniverseSettings.Resolution = Resolution.Daily
        self.AddUniverse(self.CoarseSelectionFunction) 
        self.averages = { }
        self.rebalanceTime = datetime.min
        self.RSImin = 30
        self.RSImax = 40
        self.activeStocks = set()
        self.portfolioTargets = []
        self.selected = []
        
    
    def CoarseSelectionFunction(self, universe):  
        if self.Time <= self.rebalanceTime:
            return self.Universe.Unchanged
        self.selected = []
        universe = sorted(universe, key=lambda c: c.DollarVolume, reverse=True)  
        universe = [c for c in universe if c.Price > 10][:2000]
        for coarse in universe:  
            symbol = coarse.Symbol
            history = self.History(symbol, 11, Resolution.Daily)
            self.averages[symbol] = SelectionData(history) 
            self.averages[symbol].update(self.Time, coarse.AdjustedPrice)
            
            if  int(self.averages[symbol].rsi.Current.Value) < self.RSImax and int(self.averages[symbol].rsi.Current.Value) > self.RSImin:
                self.Debug(int(self.averages[symbol].rsi.Current.Value))
                self.selected.append(symbol)
        self.rebalanceTime = self.Time + timedelta(5)
        return self.selected[:5]
        
    def OnSecuritiesChanged(self, changes):
        # close positions in removed securities
        for x in changes.RemovedSecurities:
            self.Liquidate(x.Symbol)
            if x.Symbol in self.activeStocks:
                self.activeStocks.remove(x.Symbol)
        
        # can't open positions here since data might not be added correctly yet
        for x in changes.AddedSecurities:
            self.Securities[x.Symbol].FeeModel = ConstantFeeModel(0)
            self.activeStocks.add(x.Symbol)   

        # adjust targets if universe has changed
        self.portfolioTargets = [PortfolioTarget(symbol, 1/len(self.activeStocks)) 
                            for symbol in self.activeStocks]
            
            
    def OnData(self, data):

        if self.portfolioTargets == []:
            return
        for symbol in self.activeStocks:
            if symbol not in data:
                return
        for symbol in self.portfolioTargets:
                    self.Debug(symbol)
        self.SetHoldings(self.portfolioTargets)
        self.portfolioTargets = []
            

class SelectionData():
    #3. Update the constructor to accept a history array
    def __init__(self, history):
        #self.slow = ExponentialMovingAverage(200)
        #self.fast = ExponentialMovingAverage(50)
        
        self.rsi = RelativeStrengthIndex(10)
        #self.macd = MovingAverageConvergenceDivergence(12, 26, 9)
        
        #4. Loop over the history data and update the indicators
        
        for data in history.itertuples():
            time = data.Index[1]
            close = data.close
            #self.fast.Update(time, close)
            #self.slow.Update(time, close)
            
            self.rsi.Update(time, close)
            #self.macd.Update(time, close)
            
            
    
    def is_ready(self):
        return self.rsi.IsReady 
        #and self.slow.IsReady and self.fast.IsReady and self.macd.IsReady
    
    def update(self, time, price):
        #self.fast.Update(time, price)
        #self.slow.Update(time, price)
            
        self.rsi.Update(time, price)
        #self.macd.Update(time, price)