Overall Statistics
Total Orders
4174
Average Win
0.58%
Average Loss
-0.57%
Compounding Annual Return
6.561%
Drawdown
65.900%
Expectancy
0.149
Start Equity
100000
End Equity
509473.01
Net Profit
409.473%
Sharpe Ratio
0.216
Sortino Ratio
0.25
Probabilistic Sharpe Ratio
0.003%
Loss Rate
43%
Win Rate
57%
Profit-Loss Ratio
1.02
Alpha
0.002
Beta
0.803
Annual Standard Deviation
0.173
Annual Variance
0.03
Information Ratio
-0.051
Tracking Error
0.121
Treynor Ratio
0.047
Total Fees
$18166.59
Estimated Strategy Capacity
$0
Lowest Capacity Asset
EEHB V4DT5T986VDX
Portfolio Turnover
1.09%
Drawdown Recovery
1291
#region imports
from AlgorithmImports import *
#endregion
import numpy as np
import datetime
from datetime import timedelta, date
import random



class BuildingMagic(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2000, 1, 1)    # Set Start Date
        #self.SetEndDate(2011, 12, 31)      # Set End Date
        self.SetCash(100_000)             # Set Cash
        self.spy = self.AddEquity("SPY", Resolution.Hour).Symbol
        self.SetBenchmark(self.spy)

        self.UniverseSettings.Resolution = Resolution.Hour
        self.UniverseSettings.Leverage = 1
        self._universe = self.add_universe(self._fundamental_function)

        ###   VARIABLES   ###
        self.shares_in_portfolio = 40

        self.buy_list = []
        

        ### DATES ###
        self.manual_trading_date = date.fromisoformat('2050-02-12')     # use YYYY-MM-DD format
        self.trading_days = [(self.Time).date()]
        self.trading_dates()
                     


    def _fundamental_function(self, fundamental: List[Fundamental]) -> List[Symbol]:

        if self.portfolio.invested and (self.Time).date() not in self.trading_days:
            return Universe.Unchanged
        
        self.liquidate()
        self.buy_list.clear()
        
        filtered = [x for x in fundamental]
    

        ### RANDOMIZE ###
        self.buy_list = self.get_random_fundamentals(filtered, self.shares_in_portfolio +50 )
        

        return [x.Symbol for x in self.buy_list]

        

    def OnData(self, slice: Slice) -> None:

        if self.portfolio.invested and (self.Time).date() not in self.trading_days:
            return
        
        if len(self.buy_list) < self.shares_in_portfolio /2:
            return

        if self.Securities[self.spy].Exchange.ExchangeOpen:
            self.sell_and_buy(self.buy_list)      
            self.trading_days.pop(0)



    def get_random_fundamentals(self, fundamentals_list, count):
        # Make sure count doesn't exceed the list length
        count = min(count, len(fundamentals_list))
        return random.sample(fundamentals_list, count)


    def sell_and_buy(self, buy_list):
        
        self.liquidate()
        
        if len(buy_list) == 0:
            return
        holding = round((1/self.shares_in_portfolio),3)
        for symbol in buy_list:
            if  self.securities[symbol.symbol].is_tradable:
                self.SetHoldings(symbol.symbol, holding)
                open_positions = [x.Symbol for x in self.Portfolio.Securities.Values if x.Invested]
                if len(open_positions) >= self.shares_in_portfolio:
                    break

        open_positions = [x.Symbol for x in self.Portfolio.Securities.Values if x.Invested]
        self.log(f'there are {len(open_positions)} open positions')
   

    def trading_dates(self):

        self.trading_days = self.trading_days = [
                # 2000
                date(2000, 1, 3),   # Q1
                date(2000, 7, 3),   # Q3
                # 2001
                date(2001, 1, 2),   # Q1
                date(2001, 7, 2),   # Q3
                # 2002
                date(2002, 1, 2),   # Q1
                date(2002, 7, 1),   # Q3
                # 2003
                date(2003, 1, 2),   # Q1
                date(2003, 7, 1),   # Q3
                # 2004
                date(2004, 1, 2),   # Q1
                date(2004, 7, 1),   # Q3
                # 2005
                date(2005, 1, 3),   # Q1
                date(2005, 7, 1),   # Q3
                # 2006
                date(2006, 1, 3),   # Q1
                date(2006, 7, 3),   # Q3
                # 2007
                date(2007, 1, 2),   # Q1
                date(2007, 7, 2),   # Q3
                # 2008
                date(2008, 1, 2),   # Q1
                date(2008, 7, 1),   # Q3
                # 2009
                date(2009, 1, 2),   # Q1
                date(2009, 7, 1),   # Q3
                # 2010
                date(2010, 1, 4),   # Q1
                date(2010, 7, 1),   # Q3
                # 2011
                date(2011, 1, 3),   # Q1
                date(2011, 7, 1),   # Q3
                # 2012
                date(2012, 1, 3),   # Q1
                date(2012, 7, 2),   # Q3
                # 2013
                date(2013, 1, 2),   # Q1
                date(2013, 7, 1),   # Q3
                # 2014
                date(2014, 1, 2),   # Q1
                date(2014, 7, 1),   # Q3
                # 2015
                date(2015, 1, 2),   # Q1
                date(2015, 7, 1),   # Q3
                # 2016
                date(2016, 1, 4),   # Q1
                date(2016, 7, 1),   # Q3
                # 2017
                date(2017, 1, 3),   # Q1
                date(2017, 7, 3),   # Q3
                # 2018
                date(2018, 1, 2),   # Q1
                date(2018, 7, 2),   # Q3
                # 2019
                date(2019, 1, 2),   # Q1
                date(2019, 7, 1),   # Q3
                # 2020
                date(2020, 1, 2),   # Q1
                date(2020, 7, 1),   # Q3
                # 2021
                date(2021, 1, 4),   # Q1
                date(2021, 7, 1),   # Q3
                # 2022
                date(2022, 1, 3),   # Q1
                date(2022, 7, 1),   # Q3
                # 2023
                date(2023, 1, 3),   # Q1
                date(2023, 7, 3),   # Q3
                # 2024
                date(2024, 1, 2),   # Q1
                date(2024, 7, 1),   # Q3
                # 2025
                date(2025, 1, 2),   # Q1
                date(2025, 7, 1),   # Q3
                # 2026
                date(2026, 1, 2),   # Q1
                date(2026, 7, 1),   # Q3
            ]