Overall Statistics
class UnfilledGap(QCAlgorithm):
    stopMarketTicket = None
    StopPrice = 0
    MarketOrderFillTime = datetime.min
    MarketTicket = None
    stopMarketOrderFillTime = datetime.min
    
    def Initialize(self):
        self.SetStartDate(2015, 1, 1)
        self.SetEndDate(2019, 8, 30)
        self.SetCash(100000)
        self.Equities = ["AAPL", "BA", "CAT"]
        self.Consolidators = dict()
        for Symbol in self.Equities:
            self.Consolidators[Symbol] = dict()
            self.Security = self.AddEquity(Symbol, Resolution.Minute)
            self.Window = RollingWindow[TradeBar](5)
            self.Consolidate(Symbol, Resolution.Daily, self.TradeBarHandler)
        
    def TradeBarHandler(self, TradeBar):
        self.Window.Add(TradeBar)
        
    def OnData(self, data):
        if not (self.Window.IsReady): 
            return
        
        if (self.Time - self.MarketOrderFillTime).days < 1:
            return
        if (self.Time - self.stopMarketOrderFillTime).days < 1:
            return
        
        for Symbol in self.Equities:
            if not self.Securities[Symbol].Invested:
                if self.Window[1].Low > self.Window[0].Open and self.Security.Price < self.Window[1].Low and self.Security.Price > self.Window[0].High:
                    self.MarketTicket  = self.MarketOrder(Symbol, 100, True, '1st day after gap down')
                    self.stopMarketTicket = self.StopMarketOrder(Symbol, -100, self.Window[0].Low - .10, 'Stop Loss')
                elif self.Window[2].Low > self.Window[1].Open and self.Security.Price < self.Window[2].Low and self.Security.Price > self.Window[1].High:
                    self.MarketTicket = self.MarketOrder(Symbol, 100, True, '2nd day after gap down')
                    self.stopMarketTicket = self.StopMarketOrder(Symbol, -100, self.Window[0].Low - .10, 'Stop Loss')
                elif self.Window[3].Low > self.Window[2].Open and self.Security.Price < self.Window[3].Low and self.Security.Price > self.Window[2].High:
                    self.MarketTicket = self.MarketOrder(Symbol, 100, True, '3rd day after gap down')
                    self.stopMarketTicket = self.StopMarketOrder(Symbol, -100, self.Window[0].Low - .10, 'Stop Loss')
                
            else:
                if self.Window[0].Low > self.Window[1].Low:
                    self.StopPrice = self.Window[0].Low -.10    
                    UpdateFields = UpdateOrderFields()
                    UpdateFields.StopPrice = self.StopPrice
                    self.stopMarketTicket.Update(UpdateFields)
                
    def OnOrderEvent(self, OrderEvent):
        if OrderEvent.FillQuantity == 0:
            return;
        
        Order = self.Transactions.GetOrderById(OrderEvent.OrderId)
        if self.MarketTicket is not None and self.MarketTicket.OrderId == OrderEvent.OrderId: 
            self.MarketOrderFillTime = self.Time
        if self.stopMarketTicket is not None and self.stopMarketTicket.OrderId == OrderEvent.OrderId:
            self.stopMarketOrderFillTime = self.Time
        
        FillPrice = round(OrderEvent.FillPrice*1, 2)
        ProfitPrice = round(FillPrice*1.06, 2)
        self.Log("ORDER NOTIFICATION >> {} >> Status: {} Symbol: {} Quantity: {} Fill Price: {}".format(str(Order.Tag),
                                                   str(OrderEvent.Status),
                                                   str(OrderEvent.Symbol),
                                                   str(OrderEvent.FillQuantity),
                                                   str(OrderEvent.FillPrice)));
        for Symbol in self.Equities:                                           
            if OrderEvent.Status == OrderStatus.Filled and Order.Type == OrderType.Market:
                self.LimitOrder(Symbol, -100, ProfitPrice, 'Take Profit')
            
            if OrderEvent.Status == OrderStatus.Filled and Order.Type == OrderType.StopMarket:
                self.Transactions.CancelOpenOrders()
            
            if OrderEvent.Status == OrderStatus.Filled and Order.Type == OrderType.Limit:
                self.Transactions.CancelOpenOrders()