Overall Statistics
Total Trades
10
Average Win
1.89%
Average Loss
-0.57%
Compounding Annual Return
443.817%
Drawdown
0.900%
Expectancy
1.596
Net Profit
4.587%
Sharpe Ratio
14.612
Probabilistic Sharpe Ratio
94.384%
Loss Rate
40%
Win Rate
60%
Profit-Loss Ratio
3.33
Alpha
2.154
Beta
-0.461
Annual Standard Deviation
0.175
Annual Variance
0.031
Information Ratio
7.208
Tracking Error
0.477
Treynor Ratio
-5.55
Total Fees
$11.94
Estimated Strategy Capacity
$100000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
class OpeningRangeBreakout(QCAlgorithm):
    
    openingBar = None 
    
    def Initialize(self):
        self.SetStartDate(2022, 4, 20)  
        self.SetEndDate(2022, 4, 30)  
        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 down values
        self.Schedule.On(self.DateRules.EveryDay(self.stock), self.TimeRules.AfterMarketOpen(self.stock, 30), self.First30Values)
        self.Schedule.On(self.DateRules.EveryDay(self.stock), self.TimeRules.BeforeMarketClose(self.stock, 5), self.Liquidate)
        
        #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
        self.stopMarketTicket = None
        self.stopMarketTicketShort = None
        
        
    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.995 * price)
                # self.limitOrderTicket = self.LimitOrder("SPY", -self.Portfolio["SPY"].Quantity, 1.01 * price)
                
            elif price < self.spy30Low:
                self.SetHoldings("SPY", -1.0)
                self.stopMarketTicketShort = self.StopMarketOrder("SPY", -self.Portfolio["SPY"].Quantity, 1.005 * price)
                # self.limitOrderTicketShort = self.LimitOrder("SPY", -self.Portfolio["SPY"].Quantity, .99 * price)
                
            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.995
                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.005
                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)
            
    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