Hey guys! 

I have a simple equity strategy that looks a lot like this: 

# region imports
from AlgorithmImports import *
import pandas as pd
import numpy as np
from datetime import time, datetime, timedelta
# endregion

class CombinedAlgorithm(QCAlgorithm):
    
    def Initialize(self):

        # INITIALIZE
        self.SetStartDate(2022, 1, 1)  # Set Start Date
        self.SetEndDate(2022, 5, 5)
        self.SetCash(10000)  # Set Strategy Cash
        self.symbol = self.AddEquity('AAPL', Resolution.Minute)  
        self.symbol.SetDataNormalizationMode(DataNormalizationMode.SplitAdjusted)

        # SCHEDULED EVENTS
        self.Schedule.On(self.DateRules.EveryDay(self.symbol.Symbol), self.TimeRules.AfterMarketOpen(self.symbol.Symbol, 120), self.TradingOn)
        self.Schedule.On(self.DateRules.EveryDay(self.symbol.Symbol), self.TimeRules.BeforeMarketClose(self.symbol.Symbol, 10), self.TradingOff)
        self.Schedule.On(self.DateRules.EveryDay(self.symbol.Symbol), self.TimeRules.BeforeMarketClose(self.symbol.Symbol, 2), self.LiquidateCheck)
        self.Schedule.On(self.DateRules.EveryDay(self.symbol.Symbol), self.TimeRules.BeforeMarketClose(self.symbol.Symbol), self.DayEnd)

        # TOGGLES
        self.thirty_min_reversal_sell = False
        self.initial_thirty_min_stop_sell = False
        self.initial_stop_sell = False
        self.target_sell = False
        self.target_hit = False
        self.short = False

        self.trading = False
        self.break_even = False
        self.liquidate_toggle = False
        self.invest_thirty_min = False
        self.thirty_min_trigger = False

        # VARIABLES
        self.symbol_price = 0
        self.initial_stop_price = 0
        self.initial_target_price = 0
        self.entry_price = 0

        self.trigger_thirty_min_open = 0
        self.trigger_thirty_min_close = 0
        self.trigger_thirty_min_high = 0
        self.trigger_thirty_min_low = 0

        self.SetWarmUp(timedelta(days = 25))
        self.ema = self.EMA(self.symbol.Symbol, 15, Resolution.Daily)

        # CONSOLIDATED DATA 
            # 30-Minute Bars
        thirty_min_consolidator = TradeBarConsolidator(timedelta(minutes=30))
        self.SubscriptionManager.AddConsolidator(self.symbol.Symbol, thirty_min_consolidator)
        thirty_min_consolidator.DataConsolidated += self.OnThirtyMinBar
        self.thirtyMinBarWindow = RollingWindow[TradeBar](2)

    def OnData(self, data):
        if self.IsWarmingUp:
            return

        # VARIABLES
        self.symbol_price = self.Securities[self.symbol.Symbol].Price
        held_stocks = self.Portfolio[self.symbol.Symbol].Quantity
        shares_to_buy = int(self.Portfolio.Cash / self.Securities[self.symbol.Symbol].Price)

        # ENTRY (SHORT) (HOUR TRIGGERING HOUR - FIRST TRADE OTD)
        if self.trading and self.thirty_min_trigger and not self.short:  
            if (self.symbol_price < self.trigger_thirty_min_low) and self.invest_thirty_min and not self.Portfolio.Invested:
                        self.ticket = self.MarketOrder(self.symbol.Symbol, -(shares_to_buy))

                        self.invest_thirty_min = False
                        self.thirty_min_trigger = False

                        self.initial_thirty_min_stop_sell = True
                        self.initial_stop_sell = True
                        self.initial_thirty_min_stop_price = self.trigger_thirty_min_high

                        self.thirty_min_reversal_sell = True
                        self.short = True
                        self.target_sell = True

                        self.entry_price = self.symbol_price
                        self.initial_target_price = self.entry_price * 0.99

                        self.Log(f'SHORT ENTRY (HOURLY TRIGGERING HOURLY) {self.symbol_price}') 

        # EXIT (INITIAL TARGET)
        if self.Portfolio.Invested and self.short and self.target_sell and (self.symbol_price < self.initial_target_price):
            self.MarketOrder(self.ticket.Symbol, (self.Securities[self.ticket.Symbol].Holdings.AbsoluteQuantity))
            self.target_sell = False
            self.target_hit = True
            self.Log(f'EXIT (INITIAL TARGET) {self.symbol_price}')

        # EXIT (INITIAL STOP)
        if not self.target_hit and self.Portfolio.Invested and self.short and self.initial_thirty_min_stop_sell and (self.symbol_price > self.initial_thirty_min_stop_price):
            self.MarketOrder(self.ticket.Symbol, (self.Securities[self.ticket.Symbol].Holdings.AbsoluteQuantity))
            self.initial_thirty_min_stop_sell = False
            self.thirty_min_reversal_sell = False
            self.short = False
            self.Log(f'EXIT (INITIAL STOP before target hit) {self.symbol_price}')
        if not self.target_hit and self.Portfolio.Invested and self.short and self.initial_stop_sell and (self.symbol_price > self.initial_stop_price):
            self.MarketOrder(self.ticket.Symbol, (self.Securities[self.ticket.Symbol].Holdings.AbsoluteQuantity))
            self.initial_stop_sell = False
            self.thirty_min_reversal_sell = False
            self.short = False
            self.Log(f'EXIT (INITIAL STOP before target hit) {self.symbol_price}')
        if (self.target_hit or self.break_even) and self.Portfolio.Invested and self.short and self.initial_thirty_min_stop_sell and (self.symbol_price > self.entry_price):
            self.MarketOrder(self.ticket.Symbol, (self.Securities[self.ticket.Symbol].Holdings.AbsoluteQuantity))
            self.initial_thirty_min_stop_sell = False
            self.thirty_min_reversal_sell = False
            self.short = False
            self.Log(f'EXIT (INITIAL STOP after target hit) {self.symbol_price}')
        
        # EXIT (60-MIN TRAILING STOP)
        if self.short and self.Portfolio.Invested and self.thirty_min_reversal_sell and (self.symbol_price > (self.trigger_hour_high)):
            self.MarketOrder(self.ticket.Symbol, (self.Securities[self.ticket.Symbol].Holdings.AbsoluteQuantity)) 
            self.thirty_min_reversal_sell = False
            self.initial_stop_sell = False
            self.short = False
            self.Log(f'EXIT (30-MIN REVERSAL) {self.symbol_price} and {self.trigger_thirty_min_high}')
        
        # EXIT (LIQUIDATE AT THE END OF THE DAY)
        if self.liquidate_toggle:
            self.MarketOrder(self.ticket.Symbol, (self.Securities[self.ticket.Symbol].Holdings.AbsoluteQuantity)) 
            self.liquidate_toggle = False
            self.short = False
            self.Log(f'EXIT (LIQUIDATE AT THE END OF THE DAY) {self.symbol_price}')

    # CONSOLILDATED FUNCTIONS
    def OnThirtyMinBar(self, sender, bar):
        self.thirtyMinBarWindow.Add(bar)
        if not self.thirtyMinBarWindow.IsReady:
            return
        if self.IsWarmingUp:
            return
        
        # VARIABLES 
        self.thirtyMinBarWindow.Add(bar)
        
        if not self.thirtyMinBarWindow.IsReady:
            return
        
        trigger_thirty_min = self.thirtyMinBarWindow[0]
        previous_thirty_min = self.thirtyMinBarWindow[1]

        self.trigger_thirty_min_open = trigger_thirty_min.Open
        self.trigger_thirty_min_close = trigger_thirty_min.Close
        self.trigger_thirty_min_high = trigger_thirty_min.High
        self.trigger_thirty_min_low = trigger_thirty_min.Low
        
        previous_thirty_min_high = previous_thirty_min.High
        previous_thirty_min_low = previous_thirty_min.Low

        if self.Time.hour == 10 and self.Time.minute == 0:
            self.open_thirty_low = self.trigger_thirty_min_low

        if (self.trigger_thirty_min_high < previous_thirty_min_high) and (self.trigger_thirty_min_low > previous_thirty_min_low):
            self.trigger_thirty_min_timer = self.Time.minute
            self.invest_thirty_min = True
            self.thirty_min_trigger = True
        
    # SCHEDULED EVENTS
    def TradingOn(self): # 2 hours after market open
        self.trading = True 

    def TradingOff(self): # 1 hour before market close
        self.trading = False
    
    def LiquidateCheck(self): # 2 mins before market close
        if self.Portfolio.Invested:
            self.liquidate_toggle = True
        if not self.Portfolio.Invested:
            return
    
    def DayEnd(self):
        self.trading = False
        self.short = False

I am trying to leave all the entry and exit logic the same, but trade Equity Options instead. 

I have changed two things.

contract_symbols = self.OptionChainProvider.GetOptionContractList(self.symbol.Symbol, self.Time)
expiry = min([symbol.ID.Date for symbol in contract_symbols])
filtered_symbols = [symbol for symbol in contract_symbols if symbol.ID.Date == expiry and symbol.ID.OptionRight == OptionRight.Call]
self.contract_symbol = sorted(filtered_symbols, key=lambda symbol: symbol.ID.StrikePrice)[0]

And then I changed the Market Orders to order the ‘contract_symbol’ instead of symbol.Symbol:

# self.ticket = self.MarketOrder(self.symbol.Symbol, -(shares_to_buy))
self.ticket = self.MarketOrder(self.contract_symbol, -(shares_to_buy))

Now here is the problem: 

I mess around with the code and it will either produce one of two errors. 

Runtime Error: This asset symbol (AAPL XUSJM7EPSLUU|AAPL R735QTJ8XC9X) was not found in your security list. Please add this security or check it exists before using it with 'Securities.ContainsKey("AAPL XUSJM7EPSLUU|AAPL R735QTJ8XC9X")' in SecurityManager
############ OR ############
OptionRight is only defined for SecurityType.Option, SecurityType.FutureOption, and SecurityType.IndexOption in SecurityIdentifier

Does anyone have any idea what is happening! Thank you to all those who took the time and effort to read this. I am looking forward to hear from my fellow Quants. 

Best, 

Jesse

Author