keys-nexera_1758782027.jpgSPX is not found, but is supposed to be available on the QC cloud platform

I'm having trouble accessing index data (SPX in this example) on QC cloud while backtesting. Sharing my code below:

from datetime import time, timedelta
from AlgorithmImports import *

class BankNiftyStraddleSuperTrend(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2025, 1, 1)
        # self.set_end_date(2025, 1, 15)
        self.set_cash(1000000) # 10 Lakh INR

        # Set the brokerage model for Indian markets
        # self.set_brokerage_model(BrokerageName.INTERACTIVE_BROKERS_BROKERAGE, AccountType.CASH)

        # === User-configurable parameters ===
        self.entry_time = time(9, 49)
        self.exit_time = time(15, 45)
        self.initial_sl_percent = 0.15 # 15% individual SL

        # === Index and Option setup ===
        self.index_symbol = self.add_index("SPX", Resolution.MINUTE).symbol
        self.option = self.add_index_option(self.index_symbol, Resolution.MINUTE)
        self.option.set_filter(-5, 5, timedelta(0), timedelta(7)) # Filter for near-expiry options

        # === SuperTrend Indicator on a 3-minute consolidated chart ===
        self.supertrend = self.str(self.index_symbol, 10, 3, MovingAverageType.SIMPLE, Resolution.MINUTE)
        self.consolidator = TradeBarConsolidator(timedelta(minutes=3))
        self.consolidator.data_consolidated += self.on_three_minute_bar_update
        self.register_indicator(self.index_symbol, self.supertrend, self.consolidator)

        # === Scheduled events for entry and exit ===
        self.schedule.on(self.date_rules.every_day(self.index_symbol),
                         self.time_rules.at(self.entry_time.hour, self.entry_time.minute),
                         self.enter_straddle)
        self.schedule.on(self.date_rules.every_day(self.index_symbol),
                         self.time_rules.at(self.exit_time.hour, self.exit_time.minute),
                         self.liquidate_positions)

        # === State management variables ===
        self.call_contract = None
        self.put_contract = None
        self.call_premium = 0
        self.put_premium = 0
        self.trailing_stop_active = False

    def on_data(self, data: Slice):
        # 1. Subscribe to option contracts data once we have sold them
        if self.call_contract and not data.contains_key(self.call_contract.symbol):
            self.add_index_option_contract(self.call_contract.symbol, Resolution.MINUTE)
        if self.put_contract and not data.contains_key(self.put_contract.symbol):
            self.add_index_option_contract(self.put_contract.symbol, Resolution.MINUTE)

        # 2. Check for initial stop loss (only if trailing stop is not active)
        if not self.trailing_stop_active:
            self.check_initial_stop_loss()


    def enter_straddle(self):
        # Do not enter a new position if we already have one
        if self.portfolio.invested:
            return

        # Get the options chain
        chain = self.option_chain_provider.get_option_contract_list(self.index_symbol, self.current_slice.time)
        if not chain:
            return

        # Find the ATM strike price
        underlying_price = self.securities[self.index_symbol].price
        atm_strike = sorted(chain, key=lambda x: abs(x.id.strike_price  - underlying_price))[0].id.strike_price

        # Select ATM call and put contracts for the nearest expiry
        contracts = [c for c in chain if c.id.strike_price == atm_strike]
        if len(contracts) < 2: return

        expiry = sorted([x.id.date for x in contracts])[0]
        atm_call = [c for c in contracts if c.id.option_right == OptionRight.CALL and c.id.date == expiry]
        atm_put = [c for c in contracts if c.id.option_right == OptionRight.PUT and c.id.date == expiry]

        if not atm_call or not atm_put:
            self.log("Could not find ATM Call or Put.")
            return

        self.call_contract = atm_call[0]
        self.put_contract = atm_put[0]

        # Sell the straddle
        self.market_order(self.call_contract, -1)
        self.market_order(self.put_contract, -1)
        self.log(f"Sold BANKNIFTY Straddle at Strike: {atm_strike} | Expiry: {expiry.date()}")

    def on_order_event(self, order_event: OrderEvent):
        # Store the premium received when the sell orders are filled
        if order_event.status == OrderStatus.FILLED:
            order = self.transactions.get_order_by_id(order_event.order_id)
            if order.type == OrderType.MARKET and order.direction == OrderDirection.SELL:
                if order_event.symbol == self.call_contract.symbol:
                    self.call_premium = order.price
                    self.log(f"Sold Call @ {self.call_premium}")
                elif order_event.symbol == self.put_contract.symbol:
                    self.put_premium = order.price
                    self.log(f"Sold Put @ {self.put_premium}")

            # Check if this fill was due to a stop loss, if so, activate trailing
            if self.portfolio[order_event.symbol].quantity == 0 and (self.call_premium > 0 or self.put_premium > 0):
                self.trailing_stop_active = True
                self.log(f"One leg SL hit. Activating SuperTrend trailing stop for the other leg.")


    def check_initial_stop_loss(self):
        # Check call leg SL
        if self.call_contract and self.portfolio[self.call_contract.symbol].invested:
            current_price = self.securities[self.call_contract.symbol].price
            sl_price = self.call_premium * (1 + self.initial_sl_percent)
            if current_price >= sl_price:
                self.liquidate(self.call_contract.symbol, "Initial SL Hit on Call")
                return

        # Check put leg SL
        if self.put_contract and self.portfolio[self.put_contract.symbol].invested:
            current_price = self.securities[self.put_contract.symbol].price
            sl_price = self.put_premium * (1 + self.initial_sl_percent)
            if current_price >= sl_price:
                self.liquidate(self.put_contract.symbol, "Initial SL Hit on Put")
                return

    def on_three_minute_bar_update(self, sender, bar):
        # Only run this logic if the trailing stop is active and the indicator is ready
        if not self.trailing_stop_active or not self.supertrend.is_ready:
            return

        # If price closes above the SuperTrend, it's a bullish signal. Exit short positions.
        if bar.close > self.supertrend.current.value:
            if self.portfolio.invested:
                self.log(f"SuperTrend trailing stop hit. Price {bar.close} > SuperTrend {self.supertrend.current.value}")
                self.liquidate_positions("SuperTrend Trailing Stop Hit")


    def liquidate_positions(self, reason="End of Day Exit"):
        if self.portfolio.invested:
            self.log(f"Liquidating all positions: {reason}")
            # Liquidate in a specific order to avoid margin errors
            if self.call_contract and self.portfolio[self.call_contract.symbol].invested:
                self.liquidate(self.call_contract.symbol)
            if self.put_contract and self.portfolio[self.put_contract.symbol].invested:
                self.liquidate(self.put_contract.symbol)
        
        # Reset state for the next day
        self.call_contract = None
        self.put_contract = None
        self.call_premium = 0
        self.put_premium = 0
        self.trailing_stop_active = False


Appreciate any help with this!
Â