Overall Statistics
Total Orders
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Start Equity
100000
End Equity
100000
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
-0.855
Tracking Error
0.138
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
Portfolio Turnover
0%
# region imports
from AlgorithmImports import *
# endregion

class SPXW(QCAlgorithm):
    def Initialize(self):
        #By June 2022 both SPX 0DTE Tue and Thu expirations were available
        #so daily expirations were available
        #Check SPX 0DTE daily options are available for each trading day from June 2022
        #Checks at 1 minute after market open and at 1 minute before market close
        self.SetStartDate(2022, 6, 1)
        self.SetEndDate(2024, 12, 1)

        #By the end of 2022 NDX daily 0DTE expirations were available
        #Check NDX 0DTE daily options are available for each trading day from Jan 2023
        #Checks at 1 minute after market open and at 1 minute before market close
        #self.SetStartDate(2023, 1, 1)
        #self.SetStartDate(2024, 1, 1)
        #self.SetEndDate(2024, 12, 1)
        self.SetCash(100000)

        #Check SPX 0DTE daily options are available for each trading day from June 2022
        #Checks at 1 minute after market open and at 1 minute before market close
        self.index_symbol = self.AddIndex("SPX").Symbol 
        index_option = self.AddIndexOption(self.index_symbol, "SPXW")

        #Check NDX 0DTE daily options are available for each trading day from Jan 2023
        #Checks at 1 minute after market open and at 1 minute before market close
        #self.index_symbol = self.AddIndex("NDX").Symbol 
        #index_option = self.AddIndexOption(self.index_symbol, "NDXP")
        #index_option = self.AddIndexOption(self.index_symbol, "NQX")
        index_option.SetFilter(lambda u: (u.Strikes(0, 3).Expiration(0, 0).IncludeWeeklys()))
        self.index_option_symbol = index_option.Symbol

        self.missingCount = 0

        self.schedule.on(
            self.date_rules.every_day(self.index_option_symbol),
            self.time_rules.after_market_open(self.index_option_symbol, -1),
            self.before_open
        )
        self.schedule.on(
            self.date_rules.every_day(self.index_option_symbol),
            self.time_rules.after_market_open(self.index_option_symbol, 1),
            self.after_open
        )
        #self.schedule.on(
        #    self.date_rules.every_day(self.index_option_symbol),
        #    self.time_rules.before_market_close(self.index_option_symbol, 1),
        #    self.before_end_of_day
        #)

    def before_open(self) -> None:
        self.is_check_data = False

    def after_open(self) -> None:
        self.is_check_data = True

    def before_end_of_day(self) -> None:
        self.is_check_data = True

    def OnData(self, slice: Slice) -> None:
        if self.IsMarketOpen(self.index_option_symbol):
            if self.is_check_data:
                self.is_check_data = False
                chain = slice.OptionChains.get(self.index_option_symbol)
                if not chain or not [x for x in chain]:
                    self.missingCount += 1
                    self.day = self.Time.strftime("%a")
                    self.Log(f'{self.Time} {self.day} empty n={self.missingCount}')
                #else:
                #    self.Log(f'{self.Time} OK')