Overall Statistics
class MeasuredFluorescentPinkButterfly(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2018, 1, 1)  # Set Start Date
        self.SetEndDate(2019, 1, 1)
        self.SetCash(10000)  # Set Strategy Cash
        self.AddEquity("IBM", Resolution.Minute)
        
        dailyConsolidator = TradeBarConsolidator(TimeSpan.FromDays(1))
        dailyConsolidator.DataConsolidated += self.DailyConsolidator
        self.SubscriptionManager.AddConsolidator("IBM", dailyConsolidator)
                        
        self.entrySignalMessage = ""
        self.entryPrice = None
        self.highestPrice = None
        self.timeInTrade = None
        
        self.stopLoss = 0.99
        self.trailingStopLoss = 0.984
        self.targetStop = 1.08
        
        self.closeWindow = RollingWindow[float](3)
        self.openWindow = RollingWindow[float](3)
        self.highWindow = RollingWindow[float](3)
        
        self.SetWarmup(4)
    
    def DailyConsolidator(self, sender, bar):
        self.closeWindow.Add(self.Securities["IBM"].Close)
        self.openWindow.Add(self.Securities["IBM"].Open)
        self.highWindow.Add(self.Securities["IBM"].Close)


    def OnData(self, data):
        if self.EntrySignalFired():
            if not self.Portfolio.Invested:
                quantity = self.CalculateOrderQuantity("IBM", 0.025)
                self.marketTicket = self.MarketOrder("IBM", quantity, tag=self.entrySignalMessage)
                
        if self.Portfolio.Invested and ((self.entryPrice and self.highestPrice) != None):
            if not self.Transactions.GetOpenOrders("IBM"):
                self.Debug(f"order price = {self.entryPrice}")
                self.stopMarketTicket = self.StopMarketOrder("IBM", \
                                        -self.Portfolio["IBM"].Quantity, \
                                        (self.stopLoss * self.entryPrice))
                self.limitMarketTicket = self.StopMarketOrder("IBM", \
                                        -self.Portfolio["IBM"].Quantity, \
                                        (self.targetStop * self.entryPrice))
                                        
            # if self.Securities["IBM"].Close > self.highestPrice and ((self.Securities["IBM"].Close*self.trailingStopLoss) < (self.entryPrice*self.stopLoss)):
            #     self.highestPrice = self.Securities["IBM"].Close
            #     updateFields = UpdateOrderFields()
            #     updateFields.StopPrice = self.Securities["IBM"].Close * self.trailingStopLoss
                
            if not self.Portfolio["IBM"].Invested:
                self.limitMarketTicket.Cancel()
                self.entryPrice = None
                self.highestPrice = None
                
            if self.ExitSignalFired():
                if self.Portfolio["IBM"].Invested:
                    self.Liquidate()
                    self.entryPrice = None
                    self.highestPrice = None
                
    def EntrySignalFired(self):
        if not (self.closeWindow.IsReady and self.openWindow.IsReady and self.highWindow.IsReady): return
        
        if self.highWindow[1] < self.highWindow[2] and \
            self.closeWindow[1] < self.openWindow[1] and \
            self.openWindow[0] < self.highWindow[1] and self.Securities["IBM"].Price > self.highWindow[0]:
                return True
        
        return False
        
    def ExitSignalFired(self):
        if (self.timeInTrade != None) and (self.Time - self.timeInTrade).days >= 8:
            return True
            
    def OnOrderEvent(self, orderEvent):
        order = self.Transactions.GetOrderById(orderEvent.OrderId)
        
        if order.Type == OrderType.Market and order.Status == OrderStatus.Filled:
            self.entryPrice = orderEvent.FillPrice
            self.highestPrice = orderEvent.FillPrice
            self.timeInTrade = self.Time
        
        if order.Type == OrderType.StopMarket and order.Status == OrderStatus.Filled:
            self.limitMarketTicket.Cancel()
            
        if order.Type == OrderType.Limit and order.Status == OrderStatus.Filled:
            self.stopMarketTicket.Cancel()