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 Sortino 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 -14.727 Tracking Error 0.104 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset Portfolio Turnover 0% |
from AlgorithmImports import * from datetime import datetime, timedelta class MyAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2024, 1, 5) # Set your desired start date self.SetEndDate(2024, 1, 10) # Set your desired end date self.SetCash(100000) # Set your initial capital # Add SPX and SPY indices spx = self.AddIndex("SPX", Resolution.Minute).Symbol spy = self.AddEquity("SPY", Resolution.Minute).Symbol self.optionSymbols = [] self.optionSymbols.append(Symbol.CreateCanonicalOption(spx, "SPXW", Market.USA, "?SPXW")) self.optionSymbols.append(self.AddOption(spy).Symbol) # Schedule the SelectOptionStrikes method to run every 5 minutes self.Schedule.On(self.DateRules.EveryDay('SPY'), self.TimeRules.Every(timedelta(minutes=60)), self.SelectOptionStrikes) def OnSecuritiesChanged(self, changes): self.Plot('SPX', 'Added', len(changes.AddedSecurities)) self.Plot('SPX', 'Removed', len(changes.RemovedSecurities)) self.Plot("Total Securities", len(self.ActiveSecurities.Keys)) def SelectOptionStrikes(self): if not self.IsMarketOpen(self.optionSymbols[0]): for optionSymbol in self.optionSymbols: for activeSymbol in self.ActiveSecurities.Keys: if activeSymbol.SecurityType in [SecurityType.Option, SecurityType.IndexOption] and activeSymbol.Underlying == optionSymbol.Underlying and not self.Portfolio[activeSymbol].Invested: self.RemoveOptionContract(activeSymbol) if self.CurrentSlice.ContainsKey(self.optionSymbols[0].Underlying): # Define the range around the spot price strikeRange = 20 # Loop through SPX and SPY symbols for optionSymbol in self.optionSymbols: # Get the spot price of the specified index spotPrice = self.Securities[optionSymbol.Underlying].Price self.Log(f'{optionSymbol.Underlying} spotPrice {spotPrice}') # Get the option chain for the specified index optionChain = self.OptionChainProvider.GetOptionContractList(optionSymbol, self.Time) optionChain = [x for x in optionChain if x.ID.Date.date() == self.Time.date()] if optionSymbol.Underlying == 'SPX' else [x for x in optionChain if x.ID.Date.date() == (self.Time.date() + timedelta(days=1))] self.Log(f'{optionSymbol.Underlying} length of optionChain {len(optionChain)}') # Select 20 strikes around the spot price with expiration date equal to the current date selectedStrikes = sorted([x for x in optionChain],key=lambda x: abs(x.ID.StrikePrice - spotPrice))[:40] selectedStrikes = sorted(selectedStrikes, key=lambda x: x.ID.StrikePrice) if len(selectedStrikes) > 0: self.Log(f'{optionSymbol.Underlying} length of selectedStrikes {len(selectedStrikes)} expiry: {selectedStrikes[0].ID.Date.date()} low {selectedStrikes[0].ID.StrikePrice} high {selectedStrikes[-1].ID.StrikePrice}') # Remove strikes that are no longer within the selected range and not invested for activeSymbol in self.ActiveSecurities.Keys: if activeSymbol.Underlying == optionSymbol.Underlying and activeSymbol not in selectedStrikes and not self.Portfolio[activeSymbol].Invested: self.RemoveOptionContract(activeSymbol) # Add new strikes to the universe for strike in selectedStrikes: if strike not in self.ActiveSecurities.Keys: self.AddOptionContract(strike, Resolution.Minute) # Log the total number of securities self.Debug(f"Total Securities: {len(self.ActiveSecurities.Keys)}")