Overall Statistics
Total Trades
3400
Average Win
0.46%
Average Loss
-0.34%
Compounding Annual Return
3.070%
Drawdown
13.900%
Expectancy
0.067
Net Profit
42.619%
Sharpe Ratio
0.411
Probabilistic Sharpe Ratio
1.249%
Loss Rate
55%
Win Rate
45%
Profit-Loss Ratio
1.35
Alpha
0.008
Beta
0.144
Annual Standard Deviation
0.067
Annual Variance
0.004
Information Ratio
-0.721
Tracking Error
0.146
Treynor Ratio
0.191
Total Fees
$4799.79
Estimated Strategy Capacity
$47000000.00
Lowest Capacity Asset
QQQ RIWIV7K5Z9LX
# 12268 dynamic universe warm up with Ken Lu's original setup

class FocusedAsparagusBeaver(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2010, 1, 1)
        self.SetCash(25000)
        self.userlist = ["QQQ"];
        self.symbolData = {}
        self.AddUniverse(self.MyCoarseFilterFunction)
        self.UniverseSettings.Resolution = Resolution.Hour
        

    def MyCoarseFilterFunction(self, coarse):
        symbols = [x.Symbol for x in coarse if x.Symbol.Value in self.userlist]
        
        return symbols
        
    
    def OnSecuritiesChanged(self, changes):
        for added in changes.AddedSecurities:
            self.symbolData[added.Symbol] = SymbolData(self, added.Symbol)
        
        for removed in changes.RemovedSecurities:
            if removed.Symbol in self.symbolData:
                # Remove consolidator to unregister the auto-update
                self.symbolData[removed.Symbol].Dispose()
                del self.symbolData[removed.Symbol]
                
                
    def OnData(self, data):
        if not len(data.Bars) > 0: return
        if not(self.IsMarketOpen(self.userlist[0]) and self.Time.hour >= 10):return
        

        for symbol, symbolData in self.symbolData.items():

            price = self.Securities[symbol].Price
            currentHma = symbolData.hma.Current.Value
            previousHma = symbolData.delayed_hma.Current.Value
            
            tenkan = symbolData.ichimoku.Tenkan.Current.Value
            kijun = symbolData.ichimoku.Kijun.Current.Value
            chikou = symbolData.ichimoku.Chikou.Current.Value
    
            senkou_span_a = symbolData.ichimoku.SenkouA.Current.Value
            senkou_span_b = symbolData.ichimoku.SenkouB.Current.Value
            cloud_top = max(senkou_span_a, senkou_span_b)
            cloud_bottom = min(senkou_span_a, senkou_span_b)
            
            if not self.Portfolio.Invested and currentHma > previousHma and price > previousHma and price > chikou and price > cloud_top and (tenkan >= kijun or price > kijun):
                self.SetHoldings(symbol,1)
            
            elif not self.Portfolio.Invested and currentHma < previousHma and price < previousHma and price < chikou and price < cloud_bottom and (tenkan <= kijun or price < kijun):
                self.SetHoldings(symbol, 0)    
            
            # Liquidate         
            if self.Portfolio[symbol].IsLong and currentHma < previousHma and (price < previousHma or tenkan < kijun or price < tenkan or price < kijun or price < cloud_top or price < chikou):
                self.Liquidate()
                
            elif self.Portfolio[symbol].IsShort and currentHma > previousHma and (price > previousHma or tenkan > kijun or price > tenkan or price > kijun or price > cloud_bottom or price > chikou):
                self.Liquidate()
                

class SymbolData:
    def __init__(self, algo, symbol):
        # initialize the indicators
        self.algo = algo
        self.symbol = symbol
        self.hma = HullMovingAverage(12)
        self.ichimoku = IchimokuKinkoHyo(9, 26, 26, 52, 26, 26)
        self.delayed_hma = IndicatorExtensions.Of(Delay(2), self.hma)
        
        # warm up
        history = algo.History(symbol, 52, Resolution.Hour)
        for bar in history.itertuples():
            tradeBar = TradeBar(bar.Index[1], bar.Index[0], bar.open, bar.high, bar.low, bar.close, bar.volume)
            self.hma.Update(bar.Index[1], bar.close)
            self.delayed_hma.Update(bar.Index[1], bar.close)
            self.ichimoku.Update(tradeBar)

        # Use a consolidator to update
        self.consolidator = TradeBarConsolidator(timedelta(hours=1))
        self.consolidator.DataConsolidated += self.HourHandler
        algo.SubscriptionManager.AddConsolidator(symbol, self.consolidator)
        
    def HourHandler(self, sender, bar):
        # Update the indicators
        self.hma.Update(bar.EndTime, bar.Close)
        self.delayed_hma.Update(bar.EndTime, bar.Close)
        self.ichimoku.Update(bar)
        
    def Dispose(self):
        '''Method to remove consolidator when discarding the class'''
        self.algo.SubscriptionManager.RemoveConsolidator(self.symbol, self.consolidator)