Hi all,

I am backtesting a 1DTE SPXW option strategy from 2022 to 2025. For almost 50 days I am not getting option chains. I know values exist on those days but as it works on Tradestation and I get values for the same days.

below is the code

from AlgorithmImports import *


 

class FixedFeeModel(FeeModel):

def GetOrderFee(self, parameters):

order = parameters.Order

quantity = abs(order.Quantity)

return OrderFee(CashAmount(1.0 * quantity, "USD")) # $1 per contract


 

# Define custom mid price fill model

class MidPriceFillModel(FillModel):

def MarketFill(self, asset, order):

fill = super().MarketFill(asset, order)

 

if asset.BidPrice == 0 or asset.AskPrice == 0:

# If we don't have bid/ask data, use default fill

return fill

 

# Calculate the mid price

mid_price = (asset.BidPrice + asset.AskPrice) / 2

 

# Update the fill price to mid price

fill.FillPrice = mid_price

 

return fill


 

# Define the custom slippage model

class FixedDollarSlippageModel:

def __init__(self, slippage_amount=0.1):

self.slippage_amount = slippage_amount # Fixed dollar amount per contract

 

def get_slippage_approximation(self, asset, order):

# Apply slippage based on order direction

direction = 1 if order.Direction == OrderDirection.Buy else -1

 

# Convert dollar amount to percentage of price

if asset.Price == 0:

return 0

 

slippage_percent = self.slippage_amount / asset.Price

return slippage_percent * direction


 

class OneDteIronFlyWithPnL(QCAlgorithm):

def Initialize(self):

self.SetStartDate(2022, 5, 2)

self.SetEndDate(2025, 3, 21)

self.SetCash(100000)


 

fomc_dates = [

# 2022 dates

datetime(2022, 5, 4), datetime(2022, 6, 15), datetime(2022, 7, 27),

datetime(2022, 9, 21), datetime(2022, 11, 2), datetime(2022, 12, 14),

# 2023 dates

datetime(2023, 2, 1), datetime(2023, 3, 22), datetime(2023, 5, 3),

datetime(2023, 6, 14), datetime(2023, 7, 26), datetime(2023, 9, 20),

datetime(2023, 11, 1), datetime(2023, 12, 13),

# 2024 dates

datetime(2024, 1, 31), datetime(2024, 3, 20), datetime(2024, 5, 1)

]


 

cpi_dates = [

# 2022 dates

datetime(2022, 5, 11), datetime(2022, 6, 10), datetime(2022, 7, 13),

datetime(2022, 8, 10), datetime(2022, 9, 13), datetime(2022, 10, 13),

datetime(2022, 11, 10), datetime(2022, 12, 13),

# 2023 dates

datetime(2023, 1, 12), datetime(2023, 2, 14), datetime(2023, 3, 14),

datetime(2023, 4, 12), datetime(2023, 5, 10), datetime(2023, 6, 13),

datetime(2023, 7, 12), datetime(2023, 8, 10), datetime(2023, 9, 13),

datetime(2023, 10, 12), datetime(2023, 11, 14), datetime(2023, 12, 12),

# 2024 dates

datetime(2024, 1, 11), datetime(2024, 2, 13), datetime(2024, 3, 12),

datetime(2024, 4, 10)

]


 

self.blackout_days = set((dt.date() - timedelta(days=1)) for dt in fomc_dates + cpi_dates)


 

# Set margin model and fill model in a single security initializer

def initialize_security(security):

security.set_margin_model(SecurityMarginModel.NULL)

security.set_fill_model(MidPriceFillModel())

return security

 

self.set_security_initializer(initialize_security)

self.portfolio.set_positions(SecurityPositionGroupModel.NULL)



 

self.AddIndex("VIX", Resolution.MINUTE)

# self.index_symbol_vix = self.AddIndex("VIX", Resolution.MINUTE).Symbol

self.index_symbol = self.AddIndex("SPX", Resolution.MINUTE).Symbol

weekly_option = self.AddIndexOption(self.index_symbol, "SPXW")

# weekly_option_symbol = self.AddIndexOption(self.index_symbol, "SPXW").Symbol


 

# Set pricing model

# self.Securities[weekly_option_symbol].SetPricingModel(OptionPriceModels.CrankNicolsonFD())


 

# self.symbol = self.AddEquity("SPY", Resolution.Minute).Symbol

# self.consolidator = TradeBarConsolidator(timedelta(1))

# self.SubscriptionManager.AddConsolidator(self.index_symbol_vix, self.consolidator)


 

next_trading_day = self.Time.date() + timedelta(days=1)

while not self.Securities[self.index_symbol].Exchange.DateIsOpen(next_trading_day):

next_trading_day += timedelta(days=1)


 

days_to_expiry = (next_trading_day - self.Time.date()).days


 

# weekly_option.SetFilter(lambda universe: universe.IncludeWeeklys().Strikes(-20, 20).Expiration(1,1))

weekly_option.SetFilter(lambda universe: universe.IncludeWeeklys().Expiration(days_to_expiry,days_to_expiry))


 

self.option_symbol = weekly_option.Symbol

 

self.contracts = []

self.entry_prices = {}

self.quantity = 0

self.total_credit = 0

self.credit = 0

self.invested = False

self.vix_yesterday_close = None

self.vix_today_open = None

self.change_stop_loss = 0

self.half_exit_done = 0


 

self.total_trades = 0

self.profitable_trades = 0

self.no_vix_count = 0

self.losing_trades = 0

self.profitable_trades_eod = 0

self.losing_trades_eod = 0

self.pnl_tracking = 0

self.total_pnl_qc = 0



 

# Create a custom chart

# equityChart = Chart("Equity_Compare")

 

# Add custom series with chosen colors

# equityChart.AddSeries(Series("QC_PortfolioValue", SeriesType.Line, "$", Color.Blue))

# equityChart.AddSeries(Series("MyPandL", SeriesType.Line, "$", Color.Red))

# equityChart.AddSeries(Series("Difference", SeriesType.Line, "$", Color.Green))


 

# Register the chart

# self.AddChart(equityChart)


 

self.entry_slippage_model = FixedDollarSlippageModel(0.1) # $0.10 slippage for entries

self.stop_loss_slippage_model = FixedDollarSlippageModel(0.1) # $0.10 slippage for stop losses

self.default_slippage_model = FixedDollarSlippageModel(0.0) # No extra slippage for other exits


 

# self.Schedule.On(self.DateRules.EveryDay("SPX"), self.TimeRules.At(9, 31), self.CaptureVIXClose)

self.Schedule.On(self.DateRules.EveryDay("SPX"), self.TimeRules.AfterMarketOpen("SPX", 1), self.CaptureVIXClose)

self.Schedule.On(self.DateRules.EveryDay("SPX"), self.TimeRules.At(9, 32), self.CaptureVIXOpen)

self.Schedule.On(self.DateRules.EveryDay("SPX"), self.TimeRules.At(9, 32), self.EnterStraddle)

self.Schedule.On(self.DateRules.EveryDay("SPX"), self.TimeRules.Every(TimeSpan.FromMinutes(1)), self.CheckPnL)

self.Schedule.On(self.DateRules.EveryDay("SPX"), self.TimeRules.At(15, 56), self.ExitStraddle)