Overall Statistics
Total Trades
65
Average Win
0%
Average Loss
0%
Compounding Annual Return
1.607%
Drawdown
0.300%
Expectancy
0
Net Profit
0.499%
Sharpe Ratio
2.539
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0.012
Beta
0.068
Annual Standard Deviation
0.005
Annual Variance
0
Information Ratio
-0.64
Tracking Error
0.005
Treynor Ratio
0.195
Total Fees
$65.00
from BankingIndustryStocks import BankingIndustryStocks

class BankingSectorUniverseAlgorithm(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2019, 1, 1)  # Set Start Date
        self.SetCash(100000)  # Set Strategy Cash
        # self.AddEquity("SPY", Resolution.Minute)
        self.SetUniverseSelection(BankingIndustryStocks())


    def OnData(self, data):
        for key in data.Keys:
            if not self.Portfolio[key].Invested:
                self.Log(f'Purchased {key.Value} stock')
                self.MarketOrder(key, 1)
                
    def OnSecuritiesChanged(self, changes):
        
        for security in changes.RemovedSecurities:
            self.Log(f'{security.Symbol.Value} removed from to the universe')
        
        for security in changes.AddedSecurities:
            self.Log(f'{security.Symbol.Value} added to the universe')
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel

class BankingIndustryStocks(FundamentalUniverseSelectionModel):
    '''
    This module selects the most liquid stocks listed on the Nasdaq Stock Exchange.
    '''

    def __init__(self, filterFineData = True, universeSettings = None, securityInitializer = None):
        '''Initializes a new default instance of the TechnologyUniverseModule'''
        super().__init__(filterFineData, universeSettings, securityInitializer)
        self.numberOfSymbolsCoarse = 1000
        self.numberOfSymbolsFine = 100
        self.dollarVolumeBySymbol = {}
        self.symbols = []
        self.lastMonth = -1

    def SelectCoarse(self, algorithm, coarse):
        '''
        Performs a coarse selection:
        
        -The stock must have fundamental data
        -The stock must have positive previous-day close price
        -The stock must have positive volume on the previous trading day
        '''
        if algorithm.Time.month == self.lastMonth: 
            return self.symbols

        filtered = [x for x in coarse if x.HasFundamentalData and x.Volume > 0 and x.Price > 0]
        sortedByDollarVolume = sorted(filtered, key = lambda x: x.DollarVolume, reverse=True)[:self.numberOfSymbolsCoarse]

        self.symbols.clear()
        self.dollarVolumeBySymbol.clear()
        for x in sortedByDollarVolume:
            self.symbols.append(x.Symbol)
            self.dollarVolumeBySymbol[x.Symbol] = x.DollarVolume

        return self.symbols

    def SelectFine(self, algorithm, fine):
        '''
        Performs a fine selection for companies in the Morningstar Banking Sector
        '''
        if algorithm.Time.month == self.lastMonth: 
            return self.symbols
        self.lastMonth = algorithm.Time.month

        # Filter stocks
        filteredFine = [x for x in fine if x.AssetClassification.MorningstarIndustryGroupCode == 10320]

        sortedByDollarVolume = []

        # Sort stocks on dollar volume
        sortedByDollarVolume = sorted(filteredFine, key = lambda x: self.dollarVolumeBySymbol[x.Symbol], reverse=True)
        
        self.symbols = [x.Symbol for x in sortedByDollarVolume[:self.numberOfSymbolsFine]]
        
        return self.symbols