I'm trying to build a modified version of the opening range break example that was shown in the equities bootcamp. With some help of other community members, I've managed to plot the high and low of first 30 min bar, but for I still have a few issues/questions;

  1. How come no orders are being taken? I've tried to code in if the close of current candle is higher than the opening range high, the buy 500 shares and vice versa
  2. Does anyone have any examples of how to set a trailing stop if I'm using self.SetHoldings? The only examples in the bootcamp feature fixed units (i.e. 500 units in my example below). I'd like to change this to use self.SetHoldings but I'm hesitant to do so because I've not yet found a way to set a trailing stop if I use self.SetHoldings

Sharing my code below - thanks for any help!

# First 30 minutes Highest High and Lowest Low

# -------------------------
STOCK = "SPY"; PERIOD = 30;
# -------------------------

class OpeningRangeBreakout(QCAlgorithm):
    
    # Order ticket for our stop order, Datetime when stop order was last hit
    stopMarketTicket = None
    stopMarketOrderFillTime = datetime.min
    highestSPYPrice = -1

    def Initialize(self):
        self.SetStartDate(2021, 9, 1)  
        self.SetEndDate(2021, 9, 10)  
        self.SetCash(100000) 
        self.stock = self.AddEquity(STOCK, Resolution.Minute).Symbol
        self.max = self.MAX(self.stock, PERIOD, Resolution.Minute, Field.High)
        self.min = self.MIN(self.stock, PERIOD, Resolution.Minute, Field.Low)
        self.SetWarmUp(PERIOD, Resolution.Minute)
        

    def OnData(self, data):
        # # 1. Plot the current SPY price to "Data Chart" on series "Asset Price"
        # self.Plot("Data Chart", "Asset Price", self.Securities["SPY"].Close)
        
        if self.IsWarmingUp: 
            return
        if not (self.max.IsReady or self.mi.IsReady): 
            return
        if self.Time.hour < 10 or self.Time.hour > 10 or self.Time.minute != 31: 
            return

        first_30_min_HH = self.max.Current.Value
        first_30_min_LL = self.min.Current.Value

        self.Log(f"First 30 min Highest High: {first_30_min_HH}")
        self.Log(f"First 30 min Lowest Low: {first_30_min_LL}")
        
        self.Plot("Data Chart", 'first_30_min_HH', first_30_min_HH)
        self.Plot("Data Chart", 'first_30_min_LL', first_30_min_LL)
        
        if not self.Portfolio.Invested:
            if data["SPY"].Close > first_30_min_HH:
                self.MarketOrder("SPY", 500)
                self.stopMarketTicket = self.StopMarketOrder("SPY", -500, 0.9 * self.Securities["SPY"].Close)
                
            elif data["SPY"].Close < first_30_min_LL:
                self.MarketOrder("SPY", -500)
                self.stopMarketTicket = self.StopMarketOrder("SPY", +500,  * self.Securities["SPY"].Close)
        
        else:
            
            #2. Plot the moving stop price on "Data Chart" with "Stop Price" series name
            self.Plot("Data Chart", "Stop Price",  self.highestSPYPrice * 0.9)
            
            if self.Securities["SPY"].Close > self.highestSPYPrice:
                
                self.highestSPYPrice = self.Securities["SPY"].Close
                updateFields = UpdateOrderFields()
                updateFields.StopPrice = self.highestSPYPrice * 0.9
                self.stopMarketTicket.Update(updateFields) 
            
    def OnOrderEvent(self, orderEvent):	
        
        if orderEvent.Status != OrderStatus.Filled:
            return