Overall Statistics |
Total Orders 875 Average Win 2.86% Average Loss -0.38% Compounding Annual Return 18.734% Drawdown 33.600% Expectancy 1.428 Start Equity 1000000 End Equity 8150263.29 Net Profit 715.026% Sharpe Ratio 0.762 Sortino Ratio 0.762 Probabilistic Sharpe Ratio 22.323% Loss Rate 72% Win Rate 28% Profit-Loss Ratio 7.54 Alpha 0.024 Beta 1.1 Annual Standard Deviation 0.161 Annual Variance 0.026 Information Ratio 0.598 Tracking Error 0.055 Treynor Ratio 0.112 Total Fees $39625.89 Estimated Strategy Capacity $150000000.00 Lowest Capacity Asset SPY R735QTJ8XC9X Portfolio Turnover 4.20% |
# region imports from AlgorithmImports import * # endregion class Topseven(QCAlgorithm): _winter = [ datetime(2012, 2, 2), datetime(2013, 2, 2), datetime(2014, 2, 2), datetime(2015, 2, 2), datetime(2016, 2, 2), datetime(2017, 2, 2), datetime(2018, 2, 2), datetime(2019, 2, 2), datetime(2020, 2, 2), datetime(2021, 2, 2), datetime(2022, 2, 2), datetime(2023, 2, 2), # ... ] _spring = [ datetime(2012, 4, 30), datetime(2013, 4, 30), datetime(2014, 4, 30), datetime(2015, 4, 30), datetime(2016, 4, 30), datetime(2017, 4, 30), datetime(2018, 4, 30), datetime(2019, 4, 30), datetime(2020, 4, 30), datetime(2021, 4, 30), datetime(2022, 4, 30), datetime(2023, 4, 30), # ... ] _summer = [ datetime(2012, 7, 30), datetime(2013, 7, 30), datetime(2014, 7, 30), datetime(2015, 7, 30), datetime(2016, 7, 30), datetime(2017, 7, 30), datetime(2018, 7, 30), datetime(2019, 7, 30), datetime(2020, 7, 30), datetime(2021, 7, 30), datetime(2022, 7, 30), datetime(2023, 7, 30), # ... ] _autumn = [ datetime(2012, 10, 31), datetime(2013, 10, 31), datetime(2014, 10, 31), datetime(2015, 10, 31), datetime(2016, 10, 31), datetime(2017, 10, 31), datetime(2018, 10, 31), datetime(2019, 10, 31), datetime(2020, 10, 31), datetime(2021, 10, 31), datetime(2022, 10, 31), datetime(2023, 10, 31), # ... ] def initialize(self): # Locally Lean installs free sample data, to download more data please visit https://www.quantconnect.com/docs/v2/lean-cli/datasets/downloading-data self.set_start_date(2012, 5, 18) # Set Start Date self.set_end_date(2024, 10, 30) # Set End Date self.set_cash(1000000) # Set Strategy Cash self.set_security_initializer(BrokerageModelSecurityInitializer(self.brokerage_model, FuncSecuritySeeder(self.get_last_known_prices))) self._holding_period = self.get_parameter('holding_period', 30) self._spy = self.add_equity("SPY", Resolution.DAILY) self._amzn = self.add_equity("AMZN", Resolution.DAILY, data_normalization_mode=DataNormalizationMode.RAW) self._google = self.add_equity("GOOGL", Resolution.DAILY, data_normalization_mode=DataNormalizationMode.RAW) self._meta = self.add_equity("META", Resolution.DAILY, data_normalization_mode=DataNormalizationMode.RAW) #self._spy = self.add_equity("SPY", Resolution.DAILY) self._appl = self.add_equity("AAPL", Resolution.DAILY, data_normalization_mode=DataNormalizationMode.RAW) self._msft = self.add_equity("MSFT", Resolution.DAILY, data_normalization_mode=DataNormalizationMode.RAW) self._contract_symbol = None for holidays in [self._winter, self._spring, self._summer, self._autumn]: for holiday in holidays: self.schedule.on( self.date_rules.on(self._spy.exchange.hours.get_next_market_close(holiday - timedelta(14), False)), self.time_rules.before_market_close(self._spy.symbol, 1), lambda: self.set_holdings([PortfolioTarget(self._amzn.symbol, 0.2),PortfolioTarget(self._google.symbol, 0.2), PortfolioTarget(self._meta.symbol, 0.2), PortfolioTarget(self._appl.symbol, 0.2), PortfolioTarget(self._msft.symbol, 0.2)], True) ) # Hold SPY after the holiday. self.schedule.on( self.date_rules.on(self._spy.exchange.hours.get_next_market_close(holiday + timedelta(1), False)), self.time_rules.before_market_close(self._spy.symbol, 1), lambda: self.set_holdings([PortfolioTarget(self._spy.symbol, 1)], True) ) # Sell an AMZN put contract before the holiday. self.schedule.on( self.date_rules.on(self._spy.exchange.hours.get_next_market_close(holiday - timedelta(self._holding_period), False)), self.time_rules.before_market_close(self._spy.symbol, 1), self._sell_put ) # Liquidate the put contract after the holiday. self.schedule.on( self.date_rules.on(self._spy.exchange.hours.get_next_market_close(holiday + timedelta(1), False)), self.time_rules.before_market_close(self._spy.symbol, 1), lambda: self.liquidate(self._contract_symbol) if self._contract_symbol else None ) def on_data(self, data: Slice): """on_data event is the primary entry point for your algorithm. Each new data point will be pumped in here. Arguments: data: Slice object keyed by symbol containing the stock data """ if not self._spy.holdings.invested: self.set_holdings("SPY", 1) self.debug("Purchased Stock") if self._amzn.holdings.invested: self.liquidate(self._amzn.symbol) self.liquidate(self._google.symbol) self.liquidate(self._msft.symbol) self.liquidate(self._appl.symbol) self.liquidate(self._meta.symbol) self._contract_symbol = None def _sell_put(self): symbols = [self._amzn.symbol, self._appl.symbol, self._google.symbol, self._msft.symbol, self._meta.symbol] for symbol in symbols: chain = self.option_chain(symbol).data_frame if chain.empty: return expiry_threshold = self._amzn.exchange.hours.get_next_market_close(self.time + timedelta(self._holding_period), False) expiry = chain[chain.expiry > expiry_threshold].expiry.min() self._contract_symbol = chain[ (chain.expiry == expiry) & (chain.right == OptionRight.PUT) & (chain.strike <= chain.underlyinglastprice) ].sort_values('openinterest') if self._contract_symbol.empty: return self._contract_symbol = self._contract_symbol.index[-1] self.add_option_contract(self._contract_symbol) self.set_holdings(self._contract_symbol, -0.2)