Overall Statistics
Total Trades
1
Average Win
0%
Average Loss
0%
Compounding Annual Return
28.877%
Drawdown
3.300%
Expectancy
0
Net Profit
2.653%
Sharpe Ratio
1.865
Probabilistic Sharpe Ratio
60.796%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0.044
Beta
-0.935
Annual Standard Deviation
0.108
Annual Variance
0.012
Information Ratio
1.665
Tracking Error
0.223
Treynor Ratio
-0.216
Total Fees
$1.12
Estimated Strategy Capacity
$68000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
#

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

    def Initialize(self):
        self.SetStartDate(2021, 9, 1)  
        self.SetEndDate(2021, 10, 10)  
        self.SetCash(100000) 
        self.stock = self.AddEquity("SPY", Resolution.Minute).Symbol
        self.max = self.MAX(self.stock, 30, Resolution.Minute)
        self.min = self.MIN(self.stock, 30, Resolution.Minute)
        self.SetWarmUp(timedelta(minutes = 30))
        
        self.stopMarketTicket = None
        self.stopMarketTicketShort = None
        self.highestSPYPrice = 0 # definitely higher than this
        self.lowestSPYPrice = 1000000 #almost certainly  than this...
        
        self.spy30High = 0
        self.spy30Low = 0
        
        # at 10AM the new method is called to save values
        self.Schedule.On(self.DateRules.EveryDay(self.stock), self.TimeRules.AfterMarketOpen(self.stock, 30), self.First30Values)
        
        #saves value of indcators at 10 am
    def First30Values(self):
        self.spy30High = self.max.Current.Value
        self.spy30Low = self.min.Current.Value
        
       # resets the value for next day 
    def OnEndOfDay(self):
        self.spy30High = 0
        self.spy30Low = 0
        
        

    def OnData(self, data):
       
        
        if self.IsWarmingUp: 
            return
        if not (self.max.IsReady or self.min.IsReady): 
            return
        if self.Time.hour < 10 or self.Time.hour > 10:
            return

    
        price = self.Securities[self.stock].Price
        
        if not self.Portfolio.Invested:
        
            if price > self.spy30High:
                self.SetHoldings("SPY", 1.0)
                self.stopMarketTicket = self.StopMarketOrder("SPY", -self.Portfolio["SPY"].Quantity, 0.99 * self.Securities["SPY"].High)
                
            elif price < self.spy30Low:
                self.SetHoldings("SPY", -1.0)
                self.stopMarketTicketShort = self.StopMarketOrder("SPY", -self.Portfolio["SPY"].Quantity, 1.01 * self.Securities["SPY"].High)
            
        
            #2. Plot the moving stop price on "Data Chart" with "Stop Price" series name
            self.Plot("Data Chart", "Stop Price",  self.highestSPYPrice * 0.99)
            
            if self.Securities["SPY"].High > self.highestSPYPrice:
                #2. Save the new high to highestSPYPrice; then update the stop price to 90% of highestSPYPrice
                self.highestSPYPrice = self.Securities[self.stock].High
                updateFields = UpdateOrderFields()
                updateFields.StopPrice = self.highestSPYPrice * 0.99
                if self.stopMarketTicket != None: ### your update request was returning NoneType because of your conditional logic, attempting to update tickets that did not exist
                    self.stopMarketTicket.Update(updateFields)
                    
            if self.Securities["SPY"].Low < self.lowestSPYPrice:
                #2. Save the new high to highestSPYPrice; then update the stop price to 90% of highestSPYPrice
                self.lowestSPYPrice = self.Securities[self.stock].Low
                updateFields = UpdateOrderFields()
                updateFields.StopPrice = self.lowestSPYPrice * 1.01
                if self.stopMarketTicketShort != None: ### your update request was returning NoneType because of your conditional logic, attempting to update tickets that did not exist
                    self.stopMarketTicketShort.Update(updateFields)
            
            #3. Print the new stop price with Debug()
            #self.Debug("SPY: " + str(self.highestSPYPrice) + " Stop: " + str(updateFields.StopPrice)) 
            
    def OnOrderEvent(self, orderEvent):
        if orderEvent.Status != OrderStatus.Filled:
            return
        if self.stopMarketTicket is not None and self.stopMarketTicket.OrderId == orderEvent.OrderId:
            self.stopMarketOrderFillTime = self.Time
        elif self.stopMarketTicketShort is not None and self.stopMarketTicketShort.OrderId == orderEvent.OrderId:
            self.stopMarketOrderShortFillTime = self.Time