Overall Statistics
Total Orders
179
Average Win
11.36%
Average Loss
-7.92%
Compounding Annual Return
10.025%
Drawdown
78.100%
Expectancy
0.494
Net Profit
891.298%
Sharpe Ratio
0.327
Sortino Ratio
0.279
Probabilistic Sharpe Ratio
0.018%
Loss Rate
39%
Win Rate
61%
Profit-Loss Ratio
1.43
Alpha
0.048
Beta
0.755
Annual Standard Deviation
0.239
Annual Variance
0.057
Information Ratio
0.182
Tracking Error
0.21
Treynor Ratio
0.104
Total Fees
$3024.47
Estimated Strategy Capacity
$27000000.00
Lowest Capacity Asset
CAT R735QTJ8XC9X
Portfolio Turnover
1.44%
from AlgorithmImports import *

class GrowthStocksAlgorithm(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2000, 1, 1)  # Set Start Date
        self.SetEndDate(2024, 1, 1)    # Set End Date
        self.SetCash(100000)           # Set Strategy Cash
        
        self.UniverseSettings.Resolution = Resolution.Daily
        self.AddUniverse(self.CoarseSelectionFunction, self.FineSelectionFunction)
        
        self.Schedule.On(self.DateRules.MonthStart(), self.TimeRules.At(10, 0), self.RebalancePortfolio)
        self.changes = []  # To track added securities

    def CoarseSelectionFunction(self, coarse):
        filtered_coarse = [x for x in coarse if x.DollarVolume > 1e6 and x.Price > 5]
        sorted_by_liquidity = sorted(filtered_coarse, key=lambda x: x.DollarVolume, reverse=True)
        selected_symbols = [x.Symbol for x in sorted_by_liquidity if x.Price * x.DollarVolume / x.Price > 2e9]
        return selected_symbols[:100]

    def FineSelectionFunction(self, fine):
        filtered_fine = [x for x in fine if x.OperationRatios.RevenueGrowth.OneYear > 0.0
                        and x.OperationRatios.NetIncomeGrowth.OneYear > 0.0
                        and x.EarningReports.BasicEPS.TwelveMonths > 0
                        and (x.ValuationRatios.PEGRatio > 0 and x.ValuationRatios.PEGRatio < 1.5)
                        and x.FinancialStatements.BalanceSheet.TotalEquity.Value > 0]
        
        sorted_by_growth = sorted(filtered_fine, key=lambda x: x.OperationRatios.RevenueGrowth.OneYear, reverse=True)
        return [x.Symbol for x in sorted_by_growth[:10]]
    
    def RebalancePortfolio(self):
        if self.changes is None or len(self.changes) == 0:
            return
        
        weight_per_security = 1.0 / len(self.changes)
        
        for security in self.Securities.Values:
            if security.Symbol in self.changes and not security.Invested:
                self.SetHoldings(security.Symbol, weight_per_security)
            elif security.Invested and security.Symbol not in self.changes:
                self.Liquidate(security.Symbol)
                
        self.changes = []  # Reset the changes after rebalancing

    def OnSecuritiesChanged(self, changes):
        self.changes = [x.Symbol for x in changes.AddedSecurities]