Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
-3.332
Tracking Error
0.105
Treynor Ratio
0
Total Fees
$0.00
from datetime import timedelta, time
from SymbolData import SymbolData
import math


class ErrorSubmission_Consolidator(QCAlgorithm):
    
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    Iniitalization
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""    
    def Initialize(self):
        
        #-- Date Range
        self.SetStartDate(2021, 1, 5) # Set Start Date
        self.SetEndDate(2021, 1, 15) # Set End Date

        
        #-- Starting Equity
        self.SetCash(1000000)  # Set Strategy Cash # check if will be replaced

        #---------- Universe Selection -------------
        
        self.UniverseSettings.Resolution = Resolution.Minute
        self.UniverseSettings.ExtendedMarketHours = True  # test live if work
        self.maxSymbolsFromUniverseFilter = 1 #3
        
        self.handpicked_symbolDict = {}
        
        #-- Filtered Universe
        self.AddUniverse(self.CoarseSelectionFilter, self.FineSelectionFilter)


        #---------- Alpha Generation -------------

        #-- Criteria Settings
        self.criteriaDict = {
        }


        #---------- Portfolio Construction -------------
        
        self.maxSymbolsToTrade = 10  # maxSymbols to trade

        self.symbolDict = {} # dictionary which stores symbols (contains more than symbols shortlisted for trading, also contains symbolData used during universe filtering)  # updated during universe updates + handpick selection
        self.symbolWithPositionDict = {}  # dictionary which stores symbols with position
        self.potentialTradeDict = {}  # temp dictionary to store potential symbols to trade
        
        
        #---------- Schedule to run calculation -------------
        self.schedulerInterval = 30
        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.Every(TimeSpan.FromMinutes(self.schedulerInterval)), self.runAlgo)
        
        self.consolidatorInterval = 30 # interval for consolidating tradebars e.g. to check for premarket



    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    # Coarse Selection Filter
       
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    def CoarseSelectionFilter(self, coarse):
        
        myuniverse = [x for x in coarse if x.HasFundamentalData and \
                      x.Price > 0 and x.Price <= 5.0] 

        for x in myuniverse:
            if x.Symbol not in self.symbolDict:
                self.symbolDict[x.Symbol] = SymbolData(self,x.Symbol)

            self.symbolDict[x.Symbol].updateIndicators(x.EndTime, x.AdjustedPrice, x.DollarVolume)

        myuniverse = [x for x in myuniverse if self.symbolDict[x.Symbol].dailyVolume_ratio > 1.5]

        return [x.Symbol for x in myuniverse]
        

    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    # Fine Selection Filter

    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    def FineSelectionFilter(self, fine):
        
        myuniverse = [x for x in fine]

        #-- Filter: low market cap
        myuniverse = [x for x in fine if x.CompanyProfile.MarketCap > 10000000 and \
                                         x.CompanyProfile.MarketCap < 50000000]     

        myuniverse = [x for x in myuniverse if x.SecurityReference.IsPrimaryShare == 1 and \
                                               x.SecurityReference.SecurityType == 'ST00000001' and \
                                               x.CompanyReference.IsLimitedPartnership == 0 and \
                                               x.SecurityReference.IsDepositaryReceipt == 0 ]

        return [x.Symbol for x in myuniverse[:self.maxSymbolsFromUniverseFilter]]
    
    
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    runAlgo - Main execution function for the system
        - function is triggered every x minute to check for signal and execute trades
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""    
    def runAlgo(self):
        pass

        
        
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    OnSecuritiesChanged
       - this event fires whenever we have changes to our universe
       
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    def OnSecuritiesChanged(self, changes):
        # self.Log("OnSecuritiesChanged: " + str(self.Time))
        
        for security in changes.RemovedSecurities:
            symbolData = self.symbolDict.pop(security.Symbol, None)
            if symbolData is not None:
                self.Debug(f"OnSecuritiesChanged: RemovedSecurities: {security.Symbol}")
                symbolData.removeConsolidators()
                
        for security in changes.AddedSecurities:
            self.Debug(f"OnSecuritiesChanged: AddedSecurities {security.Symbol}")
            self.addSymbolToMonitor(security.Symbol)    



    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    addSymbolToMonitor 
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""    
    def addSymbolToMonitor(self, symbol):
        #self.Debug(f"addSymbol {symbol}   {symbol.Value}")
        
        #if symbol not in self.symbolDict:
        #    self.Debug(f"add Symbol {symbol} not in self.symbolDict")
        #    self.symbolDict[symbol] = SymbolData(self,symbol)

        #self.AddEquity(symbol.Value, Resolution.Minute, Market.USA, True, 0, True)

        if self.symbolDict[symbol].toCheckForTrade == False:
            self.symbolDict[symbol].startConsolidator(self.consolidatorInterval)
    
    
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    OnData
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""    
    def OnData(self, data):
        pass
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Symbol Data

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
class SymbolData(object):
    
    def __init__(self, algorithm, symbol):
        
        self.symbol = symbol
        self.symbolValue = symbol.Value
        
        self.algorithm = algorithm

        self.toCheckForTrade = False

        #------- Consolidator -------
        self.myConsolidator = None


        #-- Average daily volume
        self.dailyVolume = 0
        self.dailyVolumeAverage = ExponentialMovingAverage(3)
        self.dailyVolume_ratio = 0



    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    # Function to update all Indicators with new price&volume data

    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    def updateIndicators(self, time, price, volume):
        self.dailyVolume = volume
        if self.dailyVolumeAverage.Update(time, volume):
            self.dailyVolume_ratio = self.dailyVolume / self.dailyVolumeAverage.Current.Value  
            

    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    set to 1) start checking for trade and 2) to run consolidator
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    def startConsolidator(self,intervalInMin):
        self.algorithm.Debug(f"startConsolidator {self.symbol}")
        self.toCheckForTrade = True
        
        self.myConsolidator = TradeBarConsolidator(timedelta(minutes=intervalInMin))
        self.myConsolidator.DataConsolidated += self.consolidatorFunction
        
        self.algorithm.SubscriptionManager.AddConsolidator(self.symbol, self.myConsolidator)        


    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    conolidatorFunction
       0500-0930 <premarket> || 930-1600 <open> || 1600-2000 <postmarket>

    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""    
    def consolidatorFunction(self,sender,bar):
        
        if bar.Time.hour == 9 and bar.Time.minute == 0: #just to print less
            self.algorithm.Debug(f"{bar.Time} consolidatorFunction  {bar.Symbol}")



    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    removeConsolidators
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    def removeConsolidators(self):
        self.algorithm.Debug(f"remove Consolidator {self.symbol}")
        self.algorithm.SubscriptionManager.RemoveConsolidator(self.symbol, self.myConsolidator)